The goal of TDD is not writing the tests first, it’s a design process where you iterate over the design as you develop new code. Instead of doing a full upfront design, you design little by little as you need more functionality.Writing test first is just a tool to force you to focus on a small part of the code, how that part should work and improve the design all the time.

Generally doing TDD at-least guarantees tests and testability. It does not provide efficiency or quality in itself (I have not found any documented evidence of this). But it does provide some minimum level of quality and encourages the developers to think about the problem in a modualized way. It also makes sure that developers write tests. We all now that writing tests after committing the code is hard because of all those excuses: late friday night, pressure, the sprint is ending and we just need some other functionality done, etc.

Another big benefit from TDD is that it also (help) eliminates the waste from created from developers implementing stuff that might be useful. No code can be written before a test-case requiring that functionality.

will make it easier to refactor your code, because of the high test coverage

makes you iterate and improve the design throughout the whole development process

high test-coverage provides excellent documentation of your code

Shortcomings of TDD

A higher number of tests can not guarantee higher code quality, it can only provide you with a minimum level of quality of the resulting product.

can be time-consuming, especially in the beginning

can be hard, especially dealing with frameworks which put constraints on your code

done wrong: can make it hard to change the code. This is because there is so many tests everywhere that verify every little part of your code all the time

can be hard to prove that it actually are more cost effective, especially in the beginning

Can make you less productive, especially if you follow a very strict TDD-model where you only do the smallest change possible to satisfy a failing test. I often feel that I would be able to solve larger part of problem at once when i do TDD.

TDD in action

Now, after providing some background, lets start doing TDD, iteration for iteration. I will show you all the steps required.

Problem description

The task is to implement an factorial method in Java. The definition of factorial is:

Examples:

0! = 1
1! = 1
2! = 2 x 1 = 2
3! = 3 x 2 x 1 = 6

Limitaions: We will limit our self to only use the primitive int type in Java. This simplifies our problem, but limits the resulting number to 32bit. this means we will only do up to 10!.

For me this feels natural. I do this to avoid having multiple of testMethods for every input value we are testing.

Summary

As you saw, we quickly found the recursive solution of this problem. Because the faculty operation is a well known problem, I would probably head straight to a similar solution without a test-first approach.

The point of this example is just to show the process and how it is performed. The benefits is generally more “visible” when the task faced is larger and more complex, where it is harder to see all the challenges required to solve upfront.

TDD gives us tested code, with shorter feedback loop, higher code confidentiality and hope of code quality and improved design. At least the developers have been forced to implement with speration of concerns in mind. More tests does not provide quality in itself and it all comes back to highly skilled developers.