The Spec
The Language
The Practice
The Books

When Not to Test First

Please Note: I have changed my views on this point. Please see: When Not to Test First Revisited

I believe there is a limit to TDD. Don't get me wrong, I'm a dedicated eXtreme Programmer and insist in practicing a pure form of the TDD rules:

  1. Write new code only if an automated test has failed
  2. Eliminate duplication
(See "Test-Driven Development By Example")

But there seems to be a point where TDD breaks down. It's when the "code" is actually "declarative code" rather than "imperative code."

Declarative code is just a set of statements about what the application is, has, or how it is configured. This can be contrasted with imperative code which is a group of statements about how the system should behave.

An example might be an html page (without any JavaScript). A completely covered test of an html page would be another rendition of the same page, perhaps in a different syntax. This test would create duplication rather than remove it. All it really seems to do is prove that the programmer is bi-lingual.

When you test for a declaration, you are stating something should be true in a test only to state it to be true again in a different way in the code. Why should we repeat the assertion in the code. Why not take the assertion out of the tests, and the code and call it something different? Why not make a declarative language for your app and just leave it as it is without tests?

It could be argued that failing to apply a test to declarative code leaves a possibility that the declarative code was not required. My question then is, where do the requirements for the tests come from? Was there a requirement for the test before it was written? Where did it come from? It came from your mind, as do declarations. There is no other thing to do before thinking and there is no substitute for that.

A test is a statement about how the application should work. Declarative code is a statement about what the application is. If you are just making a statement about what something is, then you don’t need to test it. If you are defining something's behavior, then you really should be writing your tests before you code it in order to ensure that the behavior exists and persists.

I am not saying that validating the structure of the data inappropriate. Quite the contrary, validation is desirable for discovering unintended grammatical errors in the declarative code. The benefit of a validator increases as declarative languages become more expressive and easier to make mistakes in.

I think it can be stated simply: "Don’t test declarative code, validate it", or in the positive: "Test imperatives, validate declaratives". The more I work with this theory, the more I believe it holds true and increases programming productivity.

Troy Taft is the Principal Consultant and founder of Troy Taft Consulting, a firm specializing in high value software development. He also authors a free monthly newsletter called Software Matters.

Copyright 2007 Troy Taft All rights reserved, you may print this article for your personal use.