The Case for Unit Testing

A posting on Roy Osherove's blog taking issue with a post by Joel Spolsky on the failure of methodologies like MSF got me thinking.  In particular, I (like Roy) took issue with the following section (which is actually written by Tamir Nitzan, but agreed to by Joel).

Lastly there's MSF. The author's complaint about methodologies is that they essentially transform people into compliance monkeys. "our system isn't working" -- "but we signed all the phase exits!". Intuitively, there is SOME truth in that. Any methodology that aims to promote consistency essentially has to cater to a lowest common denominator. The concept of a "repeatable process" implies that while all people are not the same, they can all produce the same way, and should all be monitored similarly. For instance, in software development, we like to have people unit-test their code. However, a good, experienced developer is about 100 times less likely to write bugs that will be uncovered during unit tests than a beginner. It is therefore practically useless for the former to write these... but most methodologies would enforce that he has to, or else you don't pass some phase. At that point, he's spending say 30% of his time on something essentially useless, which demotivates him. Since he isn't motivated to develop aggressively, he'll start giving large estimates, then not doing much, and perform his 9-5 duties to the letter. Project in crisis? Well, I did my unit tests. The rough translation of his sentence is: "methodologies encourage rock stars to become compliance monkeys, and I need everyone on my team to be a rock star".

The problem I have is that the rock stars that are being discussed are not at all like that. Having had the opportunity to work with a number of very, very good developers, I found that they embrace unit tests with enthusiasm.  And their rationale has little to do with the fact that they might be create a bug that needs to be exposed.  While that might be part of the equation, it is not the real reason for creating a unit test. 

The good developers that I've encountered are lovers of good code.  They believe that well crafted code has a beauty all of its own.  They strive to write elegant, performant classes because, well, that's what craftsmen do.  But when put under the time constraints of business, it is not always possible to create the 'best' solution every single time.  An imminent deadline might require that 'good enough' classes be checked into production.  Such is the life of a paid developer.

But you and I both know these good developers are many times more productive than their 'average' conterparts.  As a result, they frequently have time within a project schedule to refactor previously completed classes.  In fact, they enjoy going back to those 'good enough' classes and improving on them.  This attitude is one of the things I've found separates the good developers from the pack.  They are actually embarrassed by some of the 'good enough' code and feel the need to make them right.

This is where the unit tests come in.  If the completed classes are supported by a solid set of unit test, then this refactoring process can be done with a low risk to the project.  The developers know that when a modified class passes the unit tests, it is much less likely to introduce further bugs. So, rather than thinking them a waste of time, the good developers I know relish the idea of creating unit tests. Perhaps this is one of the characteristics that the rest of us would do well to emulate.