Thursday, February 21, 2008

Test Driven Development

Terry wrote a great post about "pragmatic" programming. It brings up the usefulness of test driven development(TDD). It is good that this is debated. It seems like it is almost accepted as fact that TDD is good. Period. Whenever people start accepting something without questioning, it leads to very bad things.

So I am glad that Terry questions TDD. Many folks I work with question it, too. Their arguments are different than Terry's. For example they point out that much what you code in a test has to be duplicated by QA. Of course that's not an issue for some folks, because they don't have QA, but it is an issue in larger organizations. Terry uses the example of Facebook as a large organization that uses no hard rules, i.e. TDD, for development. Also, folks I work with point out that TDD is a recurring tax. You not only spend time coding the test to start with, but you spend more time re-writing the tests every time you make changes to your code. The cost of TDD must be weighed against its benefits, you should not just accept it blindly.

To me, the value of tests greatly depends on the clients of your code. Let's say you have code whose only client is the end user, i.e. "application" code. Generally what matters for that code is that it is accepted by the end user. If it does what they want, that is all that matters as that is the only purpose for the code. I can definitely see how writing tests may not have as much value for this kind of code, though I think there is still some value to it.

Now compare this to code whose clients are other pieces of code. To make it simple imagine application code that calls infrastructure code. In this case it's harder to argue that if the end users of the application are happy, then the infrastructure code is good. Imagine if the infrastructure code has an API that is supposed to produce a formatted date. The infrastructure code could produce the wrong formatting, but the application code could work-around this to keep the end user happy. Maybe that is ok, but things get uglier when somebody "fixes" the infrastructure code, particularly if a second application uses the same infrastructure code. Having fine-grained tests for the infrastructure code becomes more valuable.

For me personally, I like using TDD, though I am not religious about it. There are times that I write a test first, then I write the code. There are other times I write the code, then a test, run the test, tweak the test, fix the code, etc. In general, I like to write tests just because I like to test my code to be sure that it works. I figure if I am going to go through the effort of doing that anyways, I might as well do it in an organized way that could be useful to others. Also, writing test code is at least as useful as writing inline documentation in your code, maybe more useful. A unit test is sample code, or darn close to it.

No comments: