So you want to know what TDD is? Or just want to find out what it is all about? Well then you are at the right place. Test Driven Development is a software development process where you use testing to develop in small cycles. You first create tests before you create production code. This might sound weird. And if you have never practiced or tried it out, then you might be skeptical. In this article I will go over the theories and reasons why TDD is practiced by a lot professional developers. But first we start with the 3 basic laws of TDD. The starting point for every TDD practitioner.
The Three Laws of TDD
So as a practitioner of TDD these are the 3 laws you need to abide to. If you can follow these laws then you are practicing TDD.
You are not allowed to write any production code unless it is to make a failing unit test pass.
So this means we first need to write a test before we write any production code. You might wonder, then what are we supposed to test? How to test something that does not exists? This is what put off many developers. But this is the starting point. We write tests for how we expect our code to work.
You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
So you write just enough test code until it fails. If it fails to compile then it fails. And this probably starts after only writing one line of code.
You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
Then after you written just enough code to make a test fail. Now you are only allowed to write just enough code to make that test pass. Not more code, just enough code. This will lock you into a cycle.
The TDD cycle
When you are doing TDD you are locked in this cycle. This cycle is TDD.
So first we write just enough test code to make it fail (1). And remember a compilation error is also failure. If you instantiate a class that does not exists, then your code fails.
Then you start writing just enough production code to make that test work (2). So you write an empty class allowing the class instantiating in the test case work.
And then we refactor if there is something to refactor (3). Step 3 can be skipped if there is nothing useful to refactor. But if you writing more complex code it does not stop at just making your tests pass. You should also spend time refactoring your code to make it more readable and clean while still making sure it passes the tests. So lock yourself into this cycle and practice. You are then doing TDD.
Is TDD stupid?
If you have never done TDD then I can see you thinking. Isn’t this going to slow me down? This kinda sounds like a waste of time to always write tests first. This cycle will also keep me from thinking and staying in the zone? It will break my flow.
But I don’t think being in the zone is necessary a good thing, it allows you to write a lot of code fast (fast != good). This TDD cycle keeps you awake and also make it easier to refocus efforts when you are disturbed. It makes you a better programmer more aware of creating clean code.
But also imagine that you where in a room full of developers all doing TDD. If you then pick any developer out of that room. His or her code would have worked at least a minute ago. Any single persons code actually worked at least a minute ago. Isn’t that amazing that we have working code most of the time? When you are not doing TDD then code most of the time does not work. You can work 4 hours straight not knowing when its going to work. Junior programmers have a hard time with this. They are just writing all kind of code left and right and then get stuck on not getting anything to work. TDD helps them, it helps you to keep focused on one part and moving on to the next and next step. Always keeping confidence that your code works, because it has always worked at least a minute ago.
It is also important to know why should we use TDD. TDD will help us solve a lot of issues and raised your code quality and discipline.
- You can not do TDD when you don’t understand the requirements. This forces you to clarify the requirements and create good thought out user stories.
- Its easy to validate your code because you have made tests for all of it.
- Your tests describes how your code works. If a new developer joins the team he just need to look at the tests to see how the code works. Isn’t that amazing? You don’t require any documentation because your tests are your documentation.
- No fear to change code. We all have had that big pile of bad code that no one dares to touch. No one knows how it works and no one wants it to become their mess. If you had tests for all your code, then you can easily change the big pile of bad code because you have tests to validate how it should work.
- Creating your tests first also encourages loose coupling. You can not test code that is heavily coupled.
- No time spend debugging. You spend more time actually writing code. Your code most of the time works so no debugging 4 hours of code writing is required.
- Its also proven that there is 40 to 80% less bugs in production code. Writing tests first makes sure more bugs are actually catched before production. The earlier bugs are found and fixed, the cheaper it is to fix them. Production bugs are very costly, the earlier we can catch bugs the cheaper they are to fix.
The downside and also to reason why some people or companies don’t start with TDD is because the process adds 10 to 30% to the initial development costs. This is just reality, this is a development process that require time to get used to. Time to get productive in it. But after a few months the productivity is actually increased then it was before TDD was implemented. At the end its worth it. It will save you time and money in the long run.
I’m starting to sound like I’m selling you TDD. But I’m only stating facts here and the only thing I want to sell you on is to just try it out for yourself. Then make up your mind. Because in the past I was also hesitant to start doing TDD. I also though that it takes more time to develop something when doing TDD. But I’m actually noticing that I was wrong. You lose so much time debugging and fixing bugs that the extra time spend writing tests first is actually less then the time you lose by fixing and debugging your code afterwards. If your code was not written for testing, then its actually harder to test and fix bugs in it. As always think about this. Thinking before coding allows you to write better code. And TDD is a way to do this.