The Glorious World of Test-Driven Development (TDD)

This article was written as an individual review assignment of PPL CSUI 2021

My father always taught me that for every work that we do, there‘s a sequence of actions that need to be done to finish the work not only efficiently, but also brings out the best value it can bring.

To build a house, you will first need to plan out and build the foundation.

To plant a tree, you will first need to prepare a shovel and fertilizer.

You get the idea.

However, do the same idea should also go for software development?

Usually, we gather the requirements and specifications, analyze, design, code, test the code, and so on until we finally deploy our software. Surely, shuffling these actions might seem like planting a tree without digging up a hole first, but this is actually kind of what we are supposed to do in a Test-Driven Development.

What exactly is Test-Driven Development?

Test-driven development is a software development practice that allows us to create specifications or requirements through tests that will be helpful for the software developers when they begin to write and implement the code for the software.

To put it simply, before we write a code, we test it out first.

When using this practice, there are steps that need to be followed during development:

  1. Write a test (RED): The step where you create a test that will fail because no implementations are made yet.
  2. Write the code (GREEN): The step where you will write code that makes the test from before pass.
  3. Improve the code (REFACTOR): The step where you clean up your code from before.
  4. Repeat.

Why do we do Test-Driven Development?

“Why do we even bother with TDD?” — a guy who hadn’t had his feet wet enough in the world of software engineering.

I asked this question a lot when I first learned about TDD in my third semester of college. So here are some reasons that might just convince the past version of myself or people who wonder about this as well:

“Programming is like exploring a dark house. You go from room to room to room. Writing the test is like turning on the light. Then you can avoid the furniture and save your shins (the clean design resulting from refactoring). Then you’re ready to explore the next room” — Kent Beck, Test-Driven Development By Example

Programming can be dark, which means that without any planning before we start coding, we may run into some confusion along the way, whether it be forgetting what input that a function may take, what output that a function returns, the logic or formula of a function, etc.

Here is a simple example of how I use a test in a recent Django project of mine to light up my coding journey:

Before coding a function that returns a range of the ideal weight from your body height, I first planned out what I think is the best way to implement this. I want the input of this function to be an integer that will represent a body height and the output of this function to be a dictionary that will contain the minimum and maximum ideal weight. After that, I put in the formulas of how to get the minimum and maximum ideal weight to the test.

With this test saved in my project, I will always be able to go back to it when I start to implement the function without worrying about forgetting the input, output, or formula.

This is another example of how a test lit up my coding experience. My project needed a model called DietProfile to save the diet profile records of the users to the database. And so, before I implement the model, I first set up a dummy record of diet profile in my test then fill it with the attributes that I think the model needs and dummy data that can be used as signs of what data type each attribute has.

With this test saved in my project, I will always be able to go back to it when I start to implement the model without worrying about forgetting the name of the model, the attributes, or the data types.

Have you ever felt tired of trying to explain your code or how to use your code to someone else? Well, there’s a thing called documentation but what if you don’t enjoy making it after you finish coding? Or what if it seems that it is too complicated to be explained in words? Have you ever thought of creating tests that explain what your code does? Well, I sure didn’t when I first started programming, but it’s actually a thing. Believe it or not, the next generation of programmers can actually read your tests to understand your code.

If you think about it, when you create tests before you start coding, that basically means that you document the code before implementing it.

Here is a simple example of how I use tests in a recent Django project of mine to be used as documentation as well:

Assuming that a new group of Django programmers will be continuing my work in this project, if they see this test, they will easily be able to tell what URL to use to call a GET request to the Diet Profile API.

Same with this test for POST request as well, but they will also be able to tell what payload to give to the Diet Profile API and the data types in each attribute when calling a POST request to create a diet profile record.

When I was in my third semester of college, little did I know that testing is one of the most important things in software engineering when it comes to projects that are huge, or will be huge. One small change to fix a bug can lead to multiple new hidden bugs. It’s really scary if you find yourself in that position when dealing with a huge project that many users depend on.

With TDD, we can prevent this from happening. Because of the iterative tests that can be repeated every time we change or add things to our code, we can make sure that there are no consequences that lead to disaster, even when the change or addition is significant.

That is all, friends!

Good luck with your projects and I hope this inspires you to try out TDD!

God bless.

References

Computer Science Undergraduate at University of Indonesia