Why We Should Start Using TDD — and not DDT
Test-Driven Development, or known as TDD. There has been many discussions about its benefits and importance. It is too something that a lot of us Software Engineers are complaining about. Because, well, it maybe not that easy and it can be a real pain for some.
Be honest, some of us only write tests just cause we’re required to do so, and end up using DDT — Development Driven Test, which means deploying the code first than later write the tests accordingly (I’m not the only one who do this, right? :”D). This may get the code coverage up, but it won’t help with preventing bugs. Since we already release the code without the tests, we might ended up taking more time fixing the bugs. Over-engineering also might occur, where the code that we write is not necessary to our system. And that’s not how TDD is intended to be.
What is TDD?
TDD is a development technique where you must write a test that fails before you write new functional code. This test-first approach doesn’t mean that we write all the test before we develop the code. We’re supposed to write test and the implementation in little chunks concurrently — with the test only ahead of the code by a couple minutes or so.
The process is called TDD Life Cycle, which divided into 3 phases:
- RED — Add a test on what what we need to implement. Follow the feature requirements as a guide. In this phase, the test is supposed to fail, cause we haven’t implemented it yet.
- GREEN — Implement the code to make your test pass. Write a straightforward solution that makes the test pass, don’t think about the best practice yet.
- REFACTOR — Now it’s time where we make our code better while maintaining to pass the test. For example, by removing code duplication and make an abstraction.
—and repeat the process
Three Rules of TDD
TDD is about making simple test and simple code. Robert C. Martin provide these three rules for practicing TDD:
Write production code only to make a failing unit test pass.
Write only enough of a unit test to fail (compilation failures are failures).
Write only enough production code to pass the one failing unit test.
How Can We Benefit from TDD?
- Fulfill the requirement. By defining in the test beforehand, it ensures that your system actually meets requirements defined for it.
- Reduce error. It reduces errors in production that we didn’t notice before
- Easier to debug. When you have a bug and a test case fail, you will know exactly where to look, what to look for and what to modify.
- Prevent new bugs. Because we write the test first, we made sure that the requirements are already defined in the test. So it prevent any new bugs when there’s a new feature or a change in the requirement.
- Save time. When we maintain our code to always pass the tests, we eventually save the time needed for debugging and finding errors.
- Simpler code. TDD help us to write only what is needed in the requirement, so no more over-engineering.
Implementing TDD
It needs practice to finally be able to get the benefits of using TDD. Just like what Ruairi O’Brien said,
“Testing is a discipline that takes time to be learned before seeing the real benefits of it.”
The first thing we need to know is how to write a test. Now here’s an example of how I implement TDD in my project using Jest.
1) Red
Here in FormSekolahku.test.js
I define a page that needs to have a certain TextFields and a certain button.
Notice that the test fails as it should be.
2) Green
Now we want to implement those features and make sure that all of the test is pass.
The test doesn't have to pass all in a single time. It’s okay to implement one feature at a time, until all the test is pass.
3) Refactor
In Refactor phase, we can fix the page stylings so that it follow the design mockup.
The modified code shouldn’t affect the test
Conclusion
Using TDD does need a proper understanding of how to write tests and some time to get familiarize with. Maybe in the beginning we would face some difficulties, but once we get the hang of it, we could see how much it increases our code quality-and our productivity. Although there are some scenarios where TDD wouldn’t really be a great idea (such as in UI development and exploratory projects that has no clear guide or requirements), in my opinion, learning about TDD is still relevant to this day.