TDD: What it is and why you should embrace it
TDD can be frustrating, but it can also lead to better code.
What is TDD?
Depending on who you talk to, you may get a different answer on this question. I like to think of TDD as a process of programming which has the main goals of writing code efficiently and as bug free as possible. By writing tests first, one can ensure that each feature of a program is accounted for with tests. This fact alone is a major selling point of TDD.
By ensuring that each feature is tested, a programmer can rest assured that the current iteration of the program is working properly (at least as assured as one can be) and that any additional features can be implemented without fear of creating bugs in the initial features. One simply has to run the tests to see if the implementation of a new feature has created any such problems.
In TDD, a programmer will not write a line of code until a test has been written. The process goes like this:
- Write a test
- Run all the tests to verify that a new test fails
- Write just enough code to pass the test
- Run the tests to verify that it passes
- Refactor the code
- Repeat if necessary
Writing code in this manor ensures that only enough code to pass the tests will be written. Programmers who use TDD have to be very disciplined and need to work for an organization that is committed to TDD. Otherwise, the tendancy to skip the test writing process will take over and the benefits of TDD will be lost.
Why TDD is superior (in my opinion)
While TDD is gaining in popularity and more and more programmers are realizing the benefits, there is still a healthy debate about it's effectiveness.
I think the main reason that some programmers find it difficult to embrace is the fact that it does not feel intuitive to write the test first. We are problem solvers, and our tendancy is to jump right in and start solving the problem. Writing the test first can feel like a highly innefficient and less productive workflow.
Ironically, one of the benefits of TDD is higher productivity from programmers who write the tests first.
As a programmer, I have experienced this first hand. For a long time, I questioned the need for all of these tests and it just didn't seem necessary or correct to start off writing tests before I had some form of code to run through it. The process felt like a handcuff.
Despite my lack of enthusiasm for this process, I knew that I must give it a fair trial before I could decide if it was good or bad. I did my best to give it a fair shot. It only took a few highly successful programming sessions to start to change my mind about TDD.
A good programmer once told me that he never wrote his best solution on the first pass. He needed to write one solution to fully understand how all of the pieces would work together and then, in essence, go back and re-write it with his improved knowledge of the problem and implementation of the solution.
In my opinion, this is where TDD really shines. The act of writing tests first acts to force us into thinking about possible solutions before we start writing the code. This effectively turns our initial solution into a much stronger and cohesive solution which can then be iterated over even further to improve. I am certain that this is one of the main reasons for the data that points to higher productivity from TDD programmers.
Another major benefit of using TDD is the fact that it forces you to break the problem down into small chunks. Rather than tackling the entire problem at once, you simply need to focus on passing the next test. This is, in my opinion a much more efficient way of programming.
If you are skeptical, I would highly encourage you to give TDD a fair try as I did. I think you will find that it is a superior way to write good code that is very easy to alter in the future. It can often be very difficult to see these benefits until you actually use TDD for a significant amount of time.
Let's do something EPIC!