TDD is A Waste of Time?

Fari Qodri
Holy Dev
Published in
5 min readJan 28, 2021
Source: https://www.trainingjournal.com/articles/features/waste-time-training-no-thanks

Developers have some kind of love-hate relationship with TDD. They love it because it’s a hard proof that convinces them that their code is bug-free, or at least bug-minimal. They hate it because sometimes it’s quite hard to do and a barrier to productivity. The example of the complain that some developers make is:

Creating tests is taking so much time, the time that I could use to do REAL coding

or a complain that is usually uttered by new developers is this:

Why should I create the tests BEFORE actually making the code? It doesn’t make sense at all

So why does TDD matter? What does it actually do besides “wasting” developers’ valuable time and energy? In the next sections, I will try to answer those questions that I used to have during my early days of programming.

Changes are Inevitable

If you have been diving in programming world for long, you probably already agree that one inevitable thing in the industry is: changes. In this section, I will try to explain a source of changes toward codes.

The Age of Collaboration

Nowadays, you cannot escape collaboration. Collaboration is everywhere. New tools and methods are created for making collaboration easier and more effective. Collaborations are making changes occur faster and faster.

Imagine that you were writing a function that checks whether a number was a prime number without writing a test for the function. On the first day, you wrote the function as follow:

After writing the code you decided to test the function manually by invoking the function with some normal cases, some edge cases. Assuming that you were a good tester, you were able to cover all the necessary cases. The function worked fine after your tests, so it was assumed that the code was valid and bug-free.

Then on the second day, your colleague discovered a faster algorithm for the function. So being a good colleague, he/she updated your code as follow:

Now the code is longer, more complicated, and hypothetically more optimal. Being a good colleague, he/she decided to test the function manually too to make sure that he/she doesn’t break you function. Unfortunately, your colleague is not as good as you are in making test cases. He/she was unable to cover all the necessary cases by missing the edge cases. It turns out that the new algorithm broke if the input was a negative number, but your colleague didn’t know that since he/she didn’t test it using that input.

The situation would work much better if you wrote the tests when writing the function. Your colleague could use your test cases to confirm that his/her new algorithm doesn’t break the code by using your good test cases. It also saves time for future changes because the persons who wrote it doesn’t have to test it manually anymore, they could just use your good test cases.

Collaboration is just one source of changes. There are many other sources of changes in this industry. However, collaboration is interesting because it involves more than one person and heavily relies on trust between each other. You trust your colleagues that they won’t break your code, and vice versa. Trust is good, but it’s not enough to keep a code bug-free. Sufficient testing and good test cases is needed to smoothen the collaboration by reducing time used for testing for future changes and keeping the code bug-free.

Fitting The Requirements

One of the principle in TDD is writing the tests BEFORE writing the code itself. After reading the previous section, you may finally realise that testing is important in the longevity of a project, but you still don’t understand why the tests should be written first before writing the actual code. Some developers might think that this is useless and doesn’t make sense at all. How could you write tests for a code that you don’t even know what the result is? The key takeaway from this question is the result of the code. How could you know the result of the code before writing it? The answer might lies on the highest abstraction: requirements.

Imagine that your project manager came to you and asked you to create products list page. One of the feature is pagination where there could be only 10 products shown at a time for efficiency reason. Your team decided to use REST API for this feature. You as a backend engineer discussed with the frontend engineer about the response format. After some discussions, it was decided that the response will look like this:

You thought that it was an easy task so you create the API right away, without making any tests. It turns out that querying the products from the database is not as simple as you thought it was. So you got frustrated for quite some time before finally figuring it out. Feeling overly satisfied that you were finally able to query the products from the database, you told the frontend engineer that the API is complete.

On the next day, your frontend engineer complains that he/she can’t process the response that your API produced, even though he/she already followed the response format contract that you both had created. After checking your API’s response, you realised that the response does not look like the format contract at all. You just query the products from the database and return them as they were, totally different with the format contract. You also didn’t include the pagination properties: the page field and the limit field. In other words, your hard work does not match the requirements!

So if we return to the initial question in this section: how could you write tests for a code that you don’t even know what the result is? My answer for this question is don’t write any piece of code if you didn’t know the result of the code yet. You should only code if you know the result already. So how do you know the result? You could derive it from the high level requirements, then translate it into the lower level tests.

Conclusion

So if we return to the initial question, is TDD a waste of time? At first, it does kind of look like it. In the beginning of your project, it slows your development progress because you have to invest your time on the hassle of creating tests, but as the your project grows, it actually saves more time than the time you use in the beginning of the project. This statement is shown in the following graph:

Source: https://www.xenonstack.com/blog/test-driven-development-java/

So how does TDD save your time? It does so by making future changes quicker and less risky by ensuring that the changes doesn’t break the code. It also saves time by making sure that the code that you write doesn’t deviate from the real purpose — the requirements.

--

--