Many software teams struggle with testing and verification of their code. There seems to be general confusion or misunderstanding around topics like unit testing, integration testing, functional testing, exploratory testing, test-driven development, test automation, and refactoring. When technical coaches introduce concepts like “levels” of executable checks, “testing strategies,” and the distinction between testing and checking, I notice many team members’ eyes glaze over. When the coaches show people how to write executable unit tests or how to do test-driven development, it seems as if they learn the mechanics in a rote way yet still aren’t sure where the various pieces fit into the bigger picture of effective software delivery. And they can’t easily judge which of the numerous topics may apply to their own workflow.
It doesn’t help that many of the terms we use are overloaded or ambiguous. What’s the difference between checking and testing software? What, exactly, is a “unit” of code? What’s the difference, if any, between integration testing and functional testing? What’s different about a regression test compared with any other kind of test? Is an executable test the same as an automated test?
It doesn’t help that each “expert” seems to have a different perception of how best to check or test software, and people hear conflicting advice. One expert insists full unit test coverage is necessary, and the next insists unit testing adds no value and shouldn’t be done at all. Between those extremes lies a whole world of opinion.
It occurs to me there’s a layer of understanding missing, between “random” or ad hoc testing and deep mastery of techniques like test-driven development, property-based testing, and mutation testing.
That’s the reason I developed a one-day, hands-on training course about unit testing that intentionally avoids going “deep” into any one of the several aspects of checking and testing software. While we avoid going deep, we ensure there’s enough hands-on practice with various techniques to give you a good sense of the role and value of each type of checking and testing. Learning objectives include the following:
- Testing vs. checking
- Code isolation for executable checking
- Clarifying confusing terminology
- What is the intent of the “test automation pyramid?”
- Why we write executable checks at different levels of abstraction
- What’s the structure of an executable test case?
- What is a regression and what is a regression test
- Example-based testing (hands-on practice)
- Property-based testing (hands-on practice as time permits)
- Mutation testing (hands-on practice as time permits)
- Test-related metrics
- What is required for a test case to be automated?
- What does “shift left” mean?
- Techniques for working with existing codebases
- Hands-on practice writing unit tests for existing code
- Hands-on practice test-driving new code
- Hands-on practice refactoring existing code
- Hands-on practice test-driving changes to existing code
- Behavior-focused vs. implementation-aware test cases
- The unit test suite as a safety net for refactoring
- Hands-on practice using an LLM assistant
- When unit testing is not useful
- Where executable unit tests fit into a CI/CD pipeline
- Relationship between testing, checking, automation, and code quality
- Relationship between test automation and reducing process waste (Lean point of view)
- Exploratory testing
At the moment, there are versions of the course for Java, C#, and Python. More are planned.
With this baseline understanding, you will be able to get high value from training that dives deeply into good practices and nuances of specific approaches and techniques for executable and automated checks and for making good use of test automation tooling to support exploratory testing and troubleshooting.
Where can you find that deeper training? I offer training in some of those areas, particularly test-driven development. My instructor-led virtual and in-person courses have received consistently good reviews.
There are quite a few training companies that offer focused training in specific aspects of the subject. These include self-guided video courses, instructor-led courses delivered in person, and instructor-led virtual courses. Another way to learn about these things is to attend meetups and user group sessions in your area and participate in code dojos that explore these techniques and tools.
If anything, there may be too many training offerings. To help you narrow down the list, let me recommend several people I know, or whose work I know, who do an especially good job in this area. This is not an exhaustive list.
- J.B. Rainsberger (Canada) – TDD training site, LinkedIn profile
- Jason Gorman (UK) – Codemanship site, LinkedIn profile
- Michael “GeePaw” Hill (US) – GeePawHill.org
- Tim Ottinger (UK) – Industrial Logic Technical Excellence Workshop, LinkedIn profile