Friday 23 October 2009

Case closed

Many heated arguments about Test-Driven Development have certain recurring reasoning on both sides. In general, developers have a hard time accepting that they need to think differently about implementation and design and/or have to alter exisitng design in order to be able to write tests. "I would need to introduce this indirection only for testing" or "There is no need for this kind of hierarchy to implement the features in the production system", and their alikes are common critiques of TDD.
Inexperienced TDD people almost invariably try to tackle these with answers like "But your design will be better this way" or "Modularity is your friend" or "Indirection is a way to build flexibilty into your code".

Obviously all of these are correct and nothing new. SOLID for example is a well-known and universal set of principles supporting the answers above. However most of the defenders of TDD are missing the point.
The point is this:
Once we've agreed that unit testing is a very efficient way to create quality software and we want to do it, there is no room for further discussion. You just have to think about the testability of your code as any other requirement you have to implement. Don't worry, you will get all the earlier mentioned: flexibility, maintainability, comprehensibility, and so on. But that shouldn't have influence on this praticular matter, because you are required to write testable code anyway. There is really nothing else to it.
Once you can get your head around this, your life as an agile programmer will be much, much easier. Mine already is.

1 comment:

Monos said...

Michael Feathers in his famous "Working Effectively with Legacy Code" defines legacy code as "Legacy code is code without tests". He goes on explaining that you can still write beautiful code without test but you don't get all the benefits of tests covering you. If you like, without tests you are writing legacy code.