Monday, November 30, 2009

Unit Testing as an afterthought

Something you hear a lot in the development world is "We'll write unit tests if we have time," which usually means "we'll go back and take a look at the huge stack of code we are about to toss over the wall to QA and try to write tests for all of it." Quite often it is the case that some tests are better than none, but as part of a mature development process, this is the wrong way to view unit tests.

If your motivation for writing unit tests is that you do it so that you can put a check mark on a development process list, you are missing the point of writing the tests in the first place. Writing the tests as you go (as mini test harnesses to help quickly test and guide development, or immediately along with development to test edge cases and cyclomatic complexity pathways) helps you to write more accurate code more quickly, which is what most people would say their goal is in the first place when they set out to commit acts of programming on their trusting clients' code bases.

Very often it is the case that writing tests for a given piece of code leads to a much better understanding of the code under test, which helps to a) write the correct code and b) be able to explain and understand it later when you need to look at it again, or when a colleague or QA tester comes calling.

Writing unit tests is like showing your work in elementary school -- the point is not to write down an answer, it is to work through the process so that you understand what you actually are doing. And with unit tests we have an added bonus: the tests are repeatable and automatable, and they inform future developers (including the author of the code) of the intent and purpose of the code under test quickly and clearly, in a way that just reading the tested code alone cannot.