We know test-driven development (TDD) since the late 1990's. Back then, Kent Beck introduced this concept for the first time as part of extreme programming. It is a well known concept, and endlessly discussed. Still today you see very different opinions and interpretations about TDD. Roy Osherove put it very nicely in his Blog Post, The various meanings of TDD: "TDD is not a clear enough concept so people see it in different light depending on who you ask".
So, in this post of our series "Design for Testability", I want to explore the following points:
The most common idea of TDD is that we write our tests first. That's true but there is more to that. It does not mean writing all the possible tests upfront. Nevertheless, some developers prefer identifying all tests before writing any production code. Therefore you have a more client centric approach. In this case all the requirements must be well defined.
Roy Osherove took a more in depth look at writing tests first in his book, The Art of Unit Testing. He explains the process of writing your tests first as an incremental process in itself:
The incremental and fine-grained approach puts more focus on a single test. You don't have to search for the reason why some tests fail after you wrote all production code. Therefore your tests end up being more robust and they give you more confidence if they fail or pass. But just because you write your tests first, does not mean that they are more robust, readable, maintainable and stable.
Test-driven development is more a skill than just following the above steps. It takes a lot practice and especially a lot of time. If done wrong, it hurts your development process and your code quality. This is why many don't do it. But if done right, the benefits definitely outweigh the drawbacks.
Well, the implications can be pretty big. As I mentioned above, test-driven development keeps your production code to a minimum level (if done right). This reduces the amount of bugs and keeps your code clean. Therefore your application is always testable. You can even go a step further by changing your software design with every new test. This does not mean that you don't have a design at all. Your tests define your design and they also detect different smells in your already given software design.
Test-driven development can help to provide testability in your application throughout its lifetime. It is a technique which has a steep learning curve but in the end you have more confidence and control over your tests.
So how do write your tests? First, last or not at all? If you want to know more about how to increase your testability check out my video about "Design for Testability".