There seems to be some confusion between Test-First Programming and Test-Driven Development (TDD).
This post explains that merely writing the tests before the code doesn’t necessarily make it TDD.
Similarities Between Test-First Programming and Test-Driven Development
It’s not hard to see why people would confuse the two, since they have many things in common.
My classification of tests distinguishes six dimensions: who, what, when, where, why, and how.
Test-First programming and Test-Driven Development score the same in five of those six dimensions: they are both automated (how) functional (what) programmer (who) tests at the unit level (where) written before the code (when).
The only difference is in why they are written.
Differences Between Test-First Programming and Test-Driven Development
Test-First Programming mandates that tests be written before the code, so that the code will always be testable. This is more efficient than having to change already written code to make it testable.
Test-First Programming doesn’t say anything about other activities in the development cycle, like requirements analysis and design.
This is a big difference with Test-Driven Development (TDD), since in TDD, the tests drive the design. Let’s take a detailed look at the TDD process of Red/Green/Refactor, to find out exactly how that differs from Test-First Programming.
In the first TDD phase we write a test. Since there is no code yet to make the test pass, this test will fail.
Unit testing frameworks like JUnit will show the result in red to indicate failure.
In both Test-First Programming and Test-Driven Development, we use this phase to record a requirement as a test.
TDD, however, goes a step further: we also explicitly design the client API. Test-First Programming is silent on how and when we should do that.
In the next phase, we write code to make the test pass. Unit testing frameworks show passing tests in green.
In Test-Driven Development, we always write the simplest possible code that makes the test pass. This allows us to keep our options open and evolve the design.
We may evolve our code using simple transformations to increase the complexity of the code enough to satisfy the requirements that are expressed in the tests.
Test-First Programming is silent on what sort of code you write in this phase and how you do it, as long as the test will pass.
In the final TDD phase, the code is refactored to improve the design of the implementation.
This phase is completely absent in Test-First Programming.
Summary of Differences
So we’ve uncovered two differences that distinguish Test-First Programming from Test-Driven Development:
- Test-Driven Development uses the Red phase to design the client API. Test-First Programming is silent on when and how you arrive at a good client API.
- Test-Driven Development splits the coding phase into two compared to Test-First Programming. In the first sub-phase (Green), the focus is on meeting the requirements. In the second sub-phase (Refactor), the focus is on creating a good design.
I think there is a lot of value in the second point. Many developers focus too much on getting the requirements implemented and forget to clean up their code. The result is an accumulation of technical debt that will slow development down over time.
TDD also splits the design activity into two. First we design the external face of the code, i.e. the API. Then we design the internal organization of the code.
This is a useful distinction as well, because the heuristics you would use to tell a good API from a bad one are different from those for good internal design.
Try Before You Buy
All in all I think Test-Driven Development provides sufficient value over Test-First Programming to give it a try.
All new things are hard, however, so be sure to practice TDD before you start applying it in the wild.
There are numerous katas that can help you with that, like the Roman Numerals Kata.
You must be logged in to post a comment.