Debugging With TDD
What is TDD?
TDD is a discipline that encourages starting with writing tests instead of the functionality itself. TDD means you first write a simple test that validates the business requirements, and then you write the functionality to make that test pass, which leads to the TDD mantra: Red, Green, Refactor.
What is Debugging
Debugging is the process of finding why is your software is not working as expected and fix it.
I’m writing this article for people who write and debug code all the time. And I will try to convince you to debug with TDD instead of guessing, brute-forcing, or relying on your memory throughout the process.
So you finished writing a great application, and now it is in production. You currently have plenty of happy customers. And suddenly, you get a bug report that says that some functionality is not working as expected. You or neither of your team did change anything recently. And no one has any idea about what lead to that problem.
It is time to debug!
Depending on the bug and how complex your system is, we can divide the debugging process into 4 points.
Understand the system and the problem at hand.
Without a proper understanding of what you are dealing with, you will end up either fixing something else or make the system worse. You should understand what the problem is and who you can reproduce it. You must learn what is the expected behavior of your system before even starting reading into the code.
Make it fail
When you understand the problem, now it’s time to make it fail consistently. So if it sometimes fails and sometimes not, then you didn’t make it fail, and some condition is still missing, and you need to learn it. This is a key point in our article, and we will talk about it in more detail in a different section.
There are many strategies that you can use for investigating issues. One can be the “5 whys," which starts with the conclusion and progresses backward by asking why questions.
After investigation and finding the root cause, you have to fix it. And make sure that the problem got fixed. Then, apply your fix, and try, then remove your fix and try again. Your trials must be reliable and repeatable.
If you are very interested in debugging and you want more information, you can read this article about debugging
Test Driven Debugging!
Why is it a big deal? And can’t we debug the usual way by trying and looking at the failure?
Of course, we are free to use any debugging or investigation strategy. And that decision depends on the knowledge we have about the issue, the system we are working with, and how critical the problem is.
I will not say that the TDD is a tool for everything, and you have to use it all the time. But what I am trying to emphasize is when to use it and what benefits it will bring you.
Do not use TDD if you are 100% sure what the problem is, and you are 100% sure what the solution is, and you know everything about the system you are working on, and the problem is very time-critical need to deploy it yesterday.
Other than the previous cases, it is better to use TDD. Because writing a test before starting looking into the implementation, needs knowledge about the functionality you are investigating and knowledge about the system you are working with. In addition to that, you will also need a complete understanding of the bug reproduction steps. All previous points will ensure that you are not solving the wrong issue and correctly solving the right one.
And back to the second action of debugging, make it fail consistently. Humans are unreliable, so you cannot guarantee a person can do something the same way multiple times. We are not equipped to do that. Neither our memory nor our brain can repeat the same processes, in the same way, every time!
So to consistently repeat the same issue repeatedly and look at it fail, you need a computer to do so. Computers are reliable, they have accurate memory, and they do not think. Therefore they consistently do whatever we told them to do.
TDD will always make you faster because there is no chance you will miss some requirements unless you don’t know about them.
- With TDD, you will never be lazy to start the beginning every time.
- With tests, you can control the system state, like time, data, and everything.
- With TDD, when you solve a problem, you will be 100% sure that you solved it unless you didn’t understand it in the first place.
- Tests are efficiently and reliably repeatable with no extra effort.
All of the above will guarantee that your solution works and will work in the future. So no need to consume extra time with regression testing with every single line of code you add.
In my experience, TDD saves a lot of time, and not doing it will hit you later. Tests are so simple, and writing them doesn’t need a significant amount of time. And be sure that if you need a significant amount of time to write some test to some feature, you do not fully understand the feature or the system you are working with. If you have another opinion, or you want to discuss this more, please let us know in the comments or contact me directly on Twitter Salem_hsn