Now that we've established that test cases can describe design, let's talk about how they can morph into tests.
Following the rhythm described above:
- Describe design in the unit test.
- Write the code to make it work.
- Validate that it works by running the test.
If we repeat this enough times we'll have a lot of these little tests that describe the design. In Hunt & Thomas's book Pragmatic Unit Testing, they suggest asking some questions at this point:
- What else can go wrong?
- Could this same kind of problem happen anywhere else?
The answers to these kind of questions detail my design around edge cases that could cause problems. Thus I start to explicitly deal with designing for and validating the design of the code in a variety of tough conditions. Now this starts to feel more like testing.
At the end of the day, my fattened test case includes all the tests I wrote while I was imagining the design of my conceived of object, and all the tests I wrote while trying to put my newborn object through a workout. There's at least as much code in the test case as in the actual class being tested.
I guess this makes it sort of "design and test," but in the end we still haven't ensured our object is bug-free. We just know where the bugs aren't—and where the design is. Unit tests have been compared with shining a flashlight into a dark room in search of a monster. Shine the light into the room and then into all the scary corners. It doesn't mean the room is monster free—just that the monster isn't standing where you've shined your flashlight.
Looking back at the three common reasons for not writing unit tests, let's substitute design for test:
- Designing takes too much time.
- How could I design first if I don't know what it does yet?
- Designing won't catch all the bugs
Those statements sound a bit different now don't they? For those making these sorts of statements about unit testing, be aware that those proficient in test-driven development might be rolling their eyes because the above design statements are what they hear. For those already doing test driven development, put down that coffee and go help others understand your cool design technique.