Why Everyone Is Crazy About TDD
9/30/20244 min read
I’ll admit, when I first started programming, I never really understood Test-Driven Development (TDD) 😅. I didn’t understand how I was writing tests for something that was yet to be implemented. Fair enough, it made sense for small functionality like testing if a function that found the square of numbers ACTUALLY found the square and wasn’t giving us random numbers. But what do I do when I am working with more complex libraries like Springboot which has layers?🤔
It also defied the natural order of testing. I build a bridge and then test it to see if it can hold my weight. I don’t test it before building it!! Why was everyone so excited about something that seemed illogical?
Thankfully, now I understand the importance of TDD and how to actually implement it 🌟. If you are sceptical or confused about TDD like I once was, this post is for you. Let’s dive into it.
What is Test-Driven Development (TDD)?
Test-Driven development is a software development process where you write your tests before you write the actual code that will fulfil them. You define the expectations and requirements upfront by writing tests. Only then do you write the code to make those tests pass.
The TDD Cycle:
Write a test: Start by writing a test that defines a specific requirement for the function or feature you’re working on. E.g. a test to ensure your database will only save a new user if their email is valid
Ensure the test fails: Since you haven’t written the implementation yet, this test should fail. This is a critical step to verify that the test itself is valid.
Write the logic: Write just enough code to make the test pass.
Refactor and repeat: Run the tests. Refactor your code if necessary, and ensure all tests continue to pass. Repeat the process for new functionality.
Why TDD is So Powerful?
While writing tests first may feel counterintuitive at first, especially when you haven’t fully fleshed out how you’re going to implement something, TDD offers a number of benefits.
1. Early Bug Detection 🐞
One of the most obvious advantages of TDD is that you detect bugs early. Since you're writing tests before the actual implementation, you're testing the smallest pieces of functionality before they ever reach production.
When you write your code and run your tests immediately, you can catch errors in real-time, saving you hours—or even days—of debugging later on. You don’t have to wait until the end of a sprint or until the QA team flags issues. The feedback loop is shortened, allowing you to write cleaner code faster.
2. Improved Code Quality 👩🏾💻
Because you're constantly thinking about how to test your code, TDD naturally leads to writing code that is more modular and easier to maintain. The focus on small, testable units of code encourages developers to break complex tasks into simpler, more manageable pieces.
Additionally, writing tests first makes you think about edge cases that might not have occurred to you during a traditional development process. As a result, your code is often more resilient, with fewer "gotchas" later on.
3. Enhanced Documentation 📄
As software evolves, its purpose and original design often become muddled. New developers join the project, teams change, and before long, the original intent of the code gets lost in translation. Well-written tests, however, can serve as a form of documentation.
Tests outline exactly how the code is supposed to behave under various circumstances. This makes it easier for someone unfamiliar with the codebase to quickly understand its purpose and expectations. Instead of relying on comments or external documentation, future developers can look at the tests to understand what the code does and what requirements it meets.
4. Improved Understanding and Clarity 🧠
Writing tests first forces you to think critically about what your code needs to do before you actually write it. In other words, TDD clarifies the requirements. By focusing on the desired outcome of a function before getting lost in the implementation details, you gain a better understanding of the problem you're solving.
This can be especially helpful in larger, more complex applications, where multiple classes and components interact with each other. Instead of getting overwhelmed by the sheer number of things to implement, you focus on one thing at a time. Write the test, implement the feature, repeat.
TDD in Complex Applications
Ok, so TDD is pretty straightforward when we are testing simple functionality. But what if I am testing a Springboot application? Springboot applications are layered, so we need to review additional considerations when trying to test one single layer.
TDD helps me start thinking of the implementation: I start thinking of the other classes I will need in my application. Although the logic isn’t actually implemented yet, I have a rough understanding of what they need to do.
Stubbing: When doing unit tests, it's important to isolate the layer we are testing so we are not testing more than one layer simultaneously. To do this, we use stubbing. This is essentially mocking other layers or classes we will use to get our desired outcome. Read more about it here.
Although TDD may appear a bit daunting at first, when you apply some patience, you will realise it's necessity in being able to build robust applications.
If you enjoyed this post, you should read:
How To Call An API With Python
How to convert a txt file into a pdf using python
Until next time,
Happy Coding! :)