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.

2 comments:

Anonymous said...

I have yet to encounter someone that argues that unit tests are a Good Thing TM. Where I've seen the effort to unit test fail is in how willing people are to burn calories on it. For most folks, including myself, a period of actively writing the unit tests along with the code is needed to see their value. Until someone experiences first-hand that it actually saves time in the long run, it's very difficult to get them to fully embrace unit tests.

I think the fundamental cause of this is the confusion of activity with accomplishment. The emphasis is almost universally to keep slinging code. Developers work harder instead of smarter because most of the time the perception is that more typing equals more work. It's like a carpenter not building a jig because those thirty minutes don't produce any walls, even if the jig would be used for days to come.

Leo said...

Very well put Sarge -- I encounter the "we don't have time" argument *all* the time, and it is impossible to counter with a short-term specific argument if folks don't embrace the quality + time savings aspects in the first place.

Great analogy about the carpenter's jig -- that's it in a nutshell.