Joel Spolsky recently posted a transcript of a conversation he and Jeff Atwood had on the Stack Overflow podcast. It’s a nice reminder to think about the situations where unit tests add value and where they add maintenance hassle.
The takeaway was that there are a few places where code coverage makes a lot of sense because change is rare and breakage has a big negative impact. These include APIs, especially plugin architectures where others are depending on the contract of your code, and mature business logic that should rarely change. You really want to think about the number of people or LOC that are depending on that code to work.
In contrast, there are a lot more places where you’re slowing down your coders and their ability to respond to customer needs.
Another contradiction Spolsky suggests: many of the same agile programmers who espouse YAGNI require an arbitrary percentage for code coverage (often close to 100%). Shouldn’t YAGNI also apply to unit tests?
I believe the key is simply thinking about what you’re doing. Here are some guidelines:
- If it’s foundation code (frameworks, libraries, etc. – anything that gets called a lot) write the tests.
- If you’re about to refactor the code, write the tests.
- Even if you’re not going to write the test, channel the spirit of Test First Development – design the code so that it’s easy to unit test should you have to later on.
I realize this might sound obvious, but a) not everyone agrees with this, and b) sometimes you can lose sight of what’s “obvious” when others are persuasively defending blind adherence to “principles”.