In the world of programming, you’re going to find a lot of developers who argue that test driven development (sometimes called TDD) just isn’t worth the effort. That’s because test driven development can be extremely time consuming. Those who have considered giving TDD a try may have run into roadblocks, run out of time, or simply run the other direction when they see what it’s going to take to get it right. On the other hand, test driven development is seeing a recent surge in popularity. And for those who are willing to invest the hours into doing it right are discovering that there are quite a few key benefits to the TDD approach.
But for the beginner, that all comes later. Let’s start at square one: a working definition of test driven development.
What is Test Driven Development?
Test driven development is a programming methodology or practice that relies on automated tests to determine when and where new code needs to be written or modified. To facilitate this, TDD uses repetition and extremely short development cycles. The programmer begins by writing an automated test case to define a specific desired function. The test case inevitably fails, and the developer corrects the failure and tries again. This continues until the code produces the desired function, at which point the programmer moves onto the next function. Essentially, rather than focusing on the development of the overall application, TDD ensures that each aspect of the code is sound before moving onto overall development.
Sounds great, right?
Well, as previously mentioned, repeatedly testing individual bits of code may not be the most efficient use of time right at first — particularly where deadlines are concerned. That said, for those who are willing to figure it out and become familiar with testing tools and methodologies, the advantages tend to outweigh the cost.
Benefits of Test Driven Development
For those who are familiar with agile practice in IT, test driven development isn’t anything all that new. With an agile practice, the ideals of iteration, feedback, adaptability, and solving specific problems before moving on help to ensure ongoing improvement of a product throughout successive development phases. And, like agile IT, it also means an overall faster turnaround.
But wait, didn’t we just claim that TDD is time consuming? How can it be prohibitively slow and also faster than other programming methodologies?
Well, it all comes down to perspective. TDD may seem slow going, because you’ll have to test and rework and test again until the code passes the test. But once that functionality has been vetted and proven successful, you won’t have to revisit it. And, once you become familiar with the process, it actually moves fairly quickly. So, you’ll be investing more time up front, but reaping less time spent down the road — for an overall faster turn around. And, because each bit of code has been developed and perfected as a separate entity, updates and changes can be made easily without fear of breaking the rest of the application.
The end result is code that is flexible, and with individual modules that can be added, removed, and improved without having to take development back to square one.
Other benefits of TDD include developing a more thorough understanding not only of the code itself, but also what exactly you want from the code. TDD forces developers to take a step closer, addressing individual issues rather than always relying on a ‘big-picture’ point of view. And because TDD requires that you address specific issues before moving on, unit tests actually function as detailed code documentation as well as usage examples of how the code is supposed to operate.
And perhaps most importantly of all, test driven development results in code that is both dependable, and also as simple as possible, because you’re only adding code where necessary in response to individual test results.
OK. So TDD is a viable and advantageous programming practise. So how is it done?
The Rules of TDD
This is a beginners’ guide, so we’re going to be simplifying things a bit here. But essentially, when you approach a TDD project, there are a few rules you need to keep in mind:
- Don’t write production code unless it’s to help a failing unit test pass.
- Only write enough of a unit test to fail.
- Only write enough production code to help a failing unit test pass.
To put it more simply, don’t write code where you don’t absolutely need to. Your job with TDD is to create tight feedback loops. That means taking baby steps, testing the smallest possible bits of code, and then adapting the code only enough to pass the test.
Those are the bearbones of test driven development. But the process is a little more involved, and could probably stand some further elaboration. So, let’s talk about TDD refactor cycles.
TDD comes down to an ongoing cycle of three steps: Red, green, refactor. You can think of these steps as follows:
- Red — What do you want the code to do?
- Green — How can you make the code do it?
- Refactor — How can you improve the code?
Again, to reiterate, the key here is that you’re not taking a big picture approach; you’re dealing with the most quantified, specific problems. So instead of asking “Does my app do what it’s supposed to do?” You’ll be asking “Does this specific, granular function of my app do what it’s supposed to?” For example, we’re not talking about whether you can use the Uber app to connect with a driver; we’re talking about whether the app is capable of sending a specific notification when the driver arrives. It’s all about tackling the small scale issues and working your way up.
When addressing a specific issue using TDD, you’re always going to start with the red phase. Your goal during the red phase is to write a test to inform the implementation of a specific feature — does the feature work?
Chances are, it does not work right at first. That’s to be expected, and it’s just fine. That’s because by identifying what you want the feature to do, and seeing where your code fails, you’ll be able to determine what kind of corrective approach may be necessary.
With a stark red test failure firmly in mind, you can now move to the green phase.
Just as green means ‘go,’ the green phase gives you the go ahead to start trying to fix the problem. Again, you’re not worrying about fixing everything all at once; you’re just focusing on the specific problem at hand — how can you make your test pass? That’s the only thing you need to worry about in this phase.
So do whatever you have to do to get it to pass.
We mean that. You don’t have to worry about following best practices or keeping everything clean here. Be as sloppy as you need to be, even create duplicate code if you have to, because right now the results are all that really matter. Clean up comes later.
Once you’ve fixed the problem and gotten back a green (meaning successful) test report, it’s on to the refactor phase.
Refactoring is where you clean up and optimize everything you’ve done, while still keeping your tests green. Honestly, the extent to which you revise and optimize is up to you, as long as you remove any and all code duplication, simplify wherever possible, and help bring your solutions up to a more professional level. And once you’re done, you move onto the next feature and start all over again.
Once you’ve addressed every feature of your application, congratulations! If you’ve followed the TDD approach effectively, then you’ll have a strong, bug-free application built from a series of adaptable modules for optimal flexibility. And yes, if you’ve developed the TDD experience necessary, you’ll even be able to save yourself some time in the process.
TDD: More Than the Sum of Its Parts
TDD is a reliable, accurate coding practice that developers can use to ensure bulletproof coding solutions throughout their entire application. But it’s also more than that. It’s a way to ensure that the end product is flexible and adaptable to the point where ongoing maintenance and newly introduced changes can be implemented without any danger to the overall product. By breaking big coding problems down into their most quantified parts, developers are able to ensure code reliability throughout.
Learning to effectively implement test driven development is no walk in the park. It takes time, it takes dedication, and it may take a complete adjustment to your entire programming mindset. But if you’re willing to stick to it, you may find that TDD really is worth all of the effort — and then some.
Want to learn more about coding and development? DevMountain offers immersive courses in Web Development, UX Design, iOS Development, and Software QA. Sign up today, and get the coding education you need to fully develop your dreams.