Why bother with TDD?

If you bought this book to learn about test-driven development, then you are probably wondering how a single practice can have such a big impact on our work. In defence of my statement that TDD is now common sense, here is a brief overview of what it can do for us.

Before the rise of test-driven development, testing and coding were traditionally two separate activities. Programmers would write code and forget about it. Quality Assurance people tried to flush out as many bugs as they could before the release. From time to time, the software would be so bug-ridden that the QA engineers had to pull the plug. Sometimes things got even worse: a system would be delivered still full of bugs and customers would besiege the support staff with angry calls and e-mails. Problems never started out big, but they were allowed to grow between coding and testing.

TDD was a conceptual shift from this practice, spreading testing over the entire development process. Problems are not allowed to grow. Guided by the “test early, test often” principle, we do a bit more work up front, but that significantly reduces the effort required to support the code.

The following quotation from “Competing on the Basis of Speed”,[1] a presentation given by Mary Poppendieck at Google Tech Talks on the 15th of December 2006, summarises the benefits of TDD very effectively:

 

When we started up in our plant...

...we had people in QA who used to try to find defects in our products, and we moved them all out on to the production line to figure out how to make stuff without defects in the first place...You will be amazed at how much faster you go when you make stuff and defects are caught when they occur instead of being found later.

 
 --Mary Poppendieck

TDD allows us to work amazingly fast, because it improves the whole process in several ways.

Quality from the start

TDD keeps problems small. Because tests take place early in the development process, rather than late, problems surface quickly and get solved before they grow. We can build quality into our products right from the start.

Early interface validation

The only way to know if an API makes sense is to use it. TDD makes developers eat their own dog food because tests are effectively the first API client. If the API does not make sense or if it is hard to use, the developers experience this first hand. Tests should be easy to write, and if they are not, then we need to change the code to make testing easier. This makes it easier for other people to use our code.

Divide and conquer

In order to test code modules in isolation, developers have to divide them into small independent chunks. This leads to better interfaces, clear division of responsibility, and easier management of code.

Safety net for the code

At the beginning of development, changes to software are quick and simple. As the code base grows, it becomes harder to modify. A simple change in one area often causes problems in a seemingly unrelated part of the code. Without tests, it soon becomes too hard and expensive to change anything. When we test all parts of the code, problems are quickly identified wherever they are.

Confidence = Productivity

As craftsmen, most developers take pride in their work and want to deliver quality software. Making changes to production code when we are not confident in the quality feels like walking on broken glass. Having tests tell us that we are on the right track, allows us to be more confident in our work and enables us to change the code faster.

Light at the end of the tunnel

Tests can be an effective way to describe specifications and requirements. If used properly, they can guide the development process, showing us what we need to implement. Once all tests pass, the work is done. This light at the end of the tunnel makes it easier to focus on the development effort.