Kevin’s comment on my previous post brings up a couple of good points which, as I thought about them, are very closely related. One is the “test-first” approach – writing unit tests prior to the code to be tested. The other is how do you ensure that you have sufficiently tested your code.
I confess that I’m not completely sold on test-first, though it was only recently that I think I realized why this is. I come from an “education” family. My family is full of teachers – I’m something of an oddity being a developer, and even so I spent six years teaching Computer Engineering Technology at a community college. So all my life I’ve heard a lot of discussion about various teaching techniques, fads, trends, etc. One complaint I’ve heard many times with increasing standardized testing is “teaching to the test.” And I realized that I get the same visceral reaction with test-first – you’re “coding to the test.”
Of course, “coding to the test” is the whole point. But this ties in with the second point concerning how do you know if you have sufficient tests. If you don’t know that you’re tests are sufficient, then you may not have coded all the functionality you really need. Just like if you “teach to the test” you may not teach students everything they really should know about the subject. I know when I’ve tried coding my tests first, they actually tend to distract me to some degree. I tend to be a bit of a “big picture” thinker while programming. Switching back and forthe between write a little test, write a little code makes me lose my train of thought.
What I probably need to do to use test first successfully is to plan out the overall functionality of the method I’m getting ready to write and write several key tests up front, not just one at a time. Then go and write the method to be tested as I normally would. Finally switch to an iterative approach to fine tune the tests and polish the code. This may not be strictly the right way to do it, but it’s probably a compromise that would work better with the way my mind works. This would probably help some with the problem of code coverage as well by writing tests while the overall functionality of the method is.
Adopting test-first programming (or test-driven development) is a paradigm shift. I encourage you to try it for a while, but find what works best for you. At least try to think about testing as you design a method or class.
“Pragmatic Unit Testing” by Andy Hunt and Dave Thomas (required reading for any professional developer) includes a checklist to assist with test coverage: http://media.pragprog.com/titles/utc2/StandaloneSummary.pdf.