TDD (test-driven development) is a software development technique (not a test design technique) whose central idea is to write tests first, before any functionality even exists, and only then write the code to implement the functionality. Please note that TDD is not the only correct or proper software development approach. You can write tests in parallel with the business logic code or after implementation, although such approaches no longer qualify as TDD. With test-driven development, tests are always written before implementation.
1. Write the test case
At this stage, you need to know what you want to test and what you expect from the functionality to be tested. This way, you can also check whether your understanding of the business logic is accurate (you may have developed “in the dark” before). It is a good idea to write your test by relying on use cases and user stories. If you do that, a correct and clear test will then serve as some form of business documentation which can be submitted to people on the business side of things so that they can validate the application logic.
2. Run the test you have written
Now you can try running the test you have written, expecting a compilation error since there is no code to be tested.
3. Write the minimum amount of code needed to pass the test
At this point, you start writing the code responsible for the business logic. Write the minimum amount of code needed for the test status to progress to “green” after the test is run, which means a pass. The important thing is to create a minimum amount of code. Do not try to write the entire module as you are only interested in the code covered by your test.
4. Refactor your code
It is important to maintain the test code according to the same standards as the production code. For that reason, during the code refactoring phase, you need to proceed with the same level of attention for both the production code and the tests.
5. Repeat the cycle
Now you have completed a full cycle. Repeat it until you have written all the tests needed to cover the business logic.
How long should TDD cycles be?
When I began learning this technique, one of the problems I encountered was the “test length”. How long should the tests be? How much code should they cover?
One of the tenets of TDD is to write the shortest possible cycles and use a large number of tests, each of them covering a small portion of the code. I found this approach to be problematic because writing a very large number of unit tests was tiresome. Having a large number of tests is not a bad thing, quite the contrary, but you must not go to extremes.
In my opinion, the size of the cycles should enable you to stay on top of what is happening in a test case easily and, more importantly, allow another developer to read and comprehend them.
When shouldn’t TDD be used?
Clearly, TDD is not a good fit for small, low-complexity projects. With such projects, the time invested in following this technique might never pay off.
When you are developing, the solution to the problem you’re working on isn’t often obvious. In a situation like that, you first try to write the code ASAP so that you can be sure you can solve the problem successfully. In the initial phase, you are not interested in error handling for the code, boundary cases, etc. During this process, TDD would only slow you down. Naturally, you need to remember to refactor the code and then write unit tests once you have found the solution.
Another case where TDD shouldn’t be used is when tests are time consuming and do not add significant value. There is no point testing trivial code which contributes no business logic and only acts as a “connector” between modules; the same applies to “boilerplate code”.
The advantages of TDD
When you develop software the traditional way (i.e. you write a larger block of code and then test it), there’s often a bug that sneaks into the code and only gets discovered some time later. It may take an hour, a few days or even a few months before the error is detected; by that time, the code may have been used in production for a long time. Another possibility is that if a large quantity of additional code is written after the error is introduced but before it is found, more time may be needed to deliver a fix.
If you develop according to TDD, most errors will be caught during testing, before the code is promoted to the test or production environment. The tests will detect the errors at the module development stage, allowing you to fix the errors yourself and engage fewer people (such as other developers, testers or the client) in the process. This, in turn, saves you time. Of course, even if you use TDD, you will not avoid errors in the code, but you will minimize the rate at which they occur.
TDD (test-driven development) is an interesting software development technique. It’s a good idea to learn it and try using it in your projects to see whether it brings you any benefits. At the same time, it should not be treated as an “oracle”, or as the only correct software development technique, because it has both advantages and disadvantages. Always remember to select the right tools and techniques depending on the specific needs of your project.