TDD: Test-Driven Development

Roberto Aureli
Data Reply IT | DataTech
5 min readSep 22, 2022

When writing software a well-known and terrifying phase of every development process is the testing one.
The main goal of a test is to ensure that the produced code is working as intended, removing all the bugs that can make it diverge from the expected, previously defined, specifications.
The simplest way of testing is to write a little program that compares a set of expected values with the actual output of a functionality, varying the inputs and exploring all the limit cases.
Just by looking at the most commonly used methods, tests are always written after the conclusion of the coding phase, hoping for a 100% score of correctness.
In this article, an atypical method is discussed trying to find the reasons behind such a different approach by showing the various phases and the general rules.

Tests before everything else

As it may be possible to guess from the introduction, TDD is a software development process guided by a strange underlying idea: tests are written to fail, and code is written to make them work.

Red phase

When the analysis is concluded and the developer has a clear idea of the functionality's specifications, the red phase is the first step toward the implementation.
With the name inspired by the classical IDEs error messages and visual hints when testing, the output of this phase is an automated, semantically and syntactically working test that must fail: when testing a nonexistent functionality we can’t expect anything else than failure.
The trickiest part of this phase is the anticipation of what the functionality will take as input and return as output, forcing the developer to think of the functionality as a black box.
Once the implemented test runs without errors and fails, the red phase is finished.

Green phase

As anticipated by the phase’s name, now the test must run successfully: the development of the functionality can start.
A minimal implementation is what is needed to pass this phase.
The real focus is exclusively on the passing of the test, with the developer writing in the fastest and dirtiest way a code that is neither elegant nor organised, it just has to make the test pass.
It’s worth stressing out the fact that during this phase the test is sacred and untouchable, it mustn’t be modified or shaped around the ongoing development of the feature to accommodate or ease the outcome.
It’s essential to assume that the output of the red phase is correct, modelling the code around the test.

Refactor

The result of the traffic light phases is a rapidly written functionality implemented with the sole scope of making the red phase’s test turn the IDE green.
Now, finally, it’s time to dignify the functionality and make it blends with the rest of the codebase.
Since production-ready code is expected by the end of this phase, all the procedures applicable to elevate the quality of the product must be applied now. That’s necessary because it’s easy to expect a fast implementation to be in the wrong part of the project, written with nonsense variables names and supported by a scarce amount of comments or in-code documentation.
An easy refactoring could include moving the code to the correct part of the project, applying design patterns, removing redundancies, applying self-documenting variables names, etc.
Once this phase it’s finished, the functionality is perfectly working, strategically integrated into the rest of the project and a candidate for future releases.

GOTO: Red Phase

TDD can be seen as an iterative approach in which the implementation of a new feature always starts from the red phase and continue throughout the full development cycle.
One thing to note is that a single iteration is meant for a single functionality: the approach is not incremental.
Once the refactoring is finished the functionality stays untouched until a modification is necessary after further changes to the specifics.

Photo by https://www.programonaut.com/

Why?

The most common approaches are typically product-driven, with the most time dedicated to the implementation and analysis phases and leaving way behind the testing one.
This type of mindset, plus the fact that writing and performing tests are notoriously tedious and time-consuming tasks, tends to make the developer or the team overlook its importance, producing inefficient tests only made for the most critical parts of the product.
By using TDD this problem is completely solved given the fact that a working test is a prerequisite for the implementation phase, bringing the test coverage near 100%.
Another critical factor in the superiority of the method is the imaginative part required in the green phase: to create a test without the functionality already available it is crucial for it to be well defined and clear in the developer's head, deepening the results of the previous analysis phase and driving the programmer in a more conscientious developing phase.
Finally, in the green phase, it’s easier to catch up on eventual bugs in the code when the functionality is continuously tested during its development: the availability of a test during the implementation makes a write-and-test approach possible, reducing the need for long debugging sessions and increasing productivity by minimizing the possible bug perimeter.

Why not?

TDD is complex. Completely reversing the way one must operate can be hard to absorb in a reasonable amount of time. Especially for the most experienced programmer used to thinking in an analyze-implement-test way, it can be even slower to reach an effective usage of TDD.
Psychologically, the inverse approach can also propagate a negative feeling of not advancing in the development, making it harder for the developer to feel the progress in the project until the “real product” is created in the green phase.

Conclusions

TDD is a great approach ideal for the ones that want 100% test coverage and a fast proceeding team on every functionality, without increasing the time dedicated to the testing session.
Moreover, it’s easy to learn but hard to master, possibly slowing down the team in the initial part of the project if not experienced in this approach.

Photo by www.techexplorist.com

--

--