Unit tests: headlights or handbrakes?

A wise colleague of mine once described unit tests as "the headlights of the project - the better they are, the faster you can go". Another wise colleague of mine claims that, in an early phase start-up, unit tests are more of a hand brake, slowing you down in the need to iterate, iterate, iterate. So who's right? Well, that depends...

The comparison of unit tests to headlights struck me as revealing something profound. I was used to selling unit testing as a requirement for stability, reliability and ultimately, happy customers. This view seems common in the literature so perhaps I can be forgiven for going along with it for so long. However, as the analogy suggests, there is another purpose for unit tests that is more aligned with the needs of a start-up. In this view, the speed with which you can refactor or re-purpose code is determined by the quality of the unit tests. The better the tests for a module, the easier it is to rewrite, optimise or even throw away and you know every chunk of your startups code is going to have one of these three happen to it every six months.

The counter argument runs along similar lines, you know any given module is going to be rewritten, optimised to death or thrown away so why write twice as much code to actually test it now, you're just going to have to rewrite the test rig later as well. In this view, anything that slows down the rate at which you can get to a (possibly pretty buggy) demo version and then early beta is a waste of effort. Testing comes later in the transition to a genuine 'alpha' product. As Guy Kawasaki probably never said "Be happy, ship crappy".

There's a third leg to this story though, although often in a startup you don't know what your final offering is actually going to be - "are we consultingware - are we SaaS?" you know the general parameters of the problem you are trying to address, the general language and framework of the customer environment in which you are working. In this sense, I think a sensible startup approach is to see themselves, at least initially as producing a high-level domain specific language for solving problems in their chosen field.

If you're building a new online music service, you may not be certain of your billing model, or your scaling parameters, but you do know that you're going to have to have a robust definition of a 'Track' and an 'Artist' and an 'Album'. These atoms of your service need to be unit tested to death - they are going to live with you throughout the process and how they relate to one another (is Track->Artist a many-to-one or many-to-many relationship?) is going to be a constant factor. Front-ends come and go but the core business logic will survive. Hence, my advice is to focus your testing efforts on that common core of your model that will survive through the twists and turns of the business. You may need to refactor it, but when you do you'll be glad you have the tests to guide you.