When I’m writing new software, one of the most important thoughts in my mind is how I’ll test to make sure it works. There are lots of ways to test software, and when you’re at your best, you should be using all of them. Sure, you should make sure that your QA team is able to verify that your code works before it goes live. You should make sure that the code passes acceptance tests, too. In the best shops, you’ll even have a robust suite of unit tests to ensure that small units of code behave the way that they should.
Lots of times, I’ll write some code, and then write a few tests to make sure that it works. That’s not a bad system. But what would happen if we flipped that process on its head? What if we wrote the tests first, then wrote code that would make the tests pass?
This method of flipping around how you write your tests is the core idea behind Test Driven Development. Instead of writing your code, you write your tests first. Then, even though you know they won’t pass, you run the tests. You watch them fail?
Why?
Because if your tests fail, you know that you’ve written an effective test. If every test you write only ever passes, that can conceal subtle bugs which make your tests ineffective. I know that I’ve written tests before which always passed. When I ran my tests to ensure my code worked, I was operating under a mistaken sense of security. It turned out that my code didn’t work, but I had no way of telling. My test had never failed, so I had no idea that it wasn’t effectively testing my code. It took until some time later that I realized my error. Sometimes, the bug even made it to production before I noticed.
After you’ve seen your test fail at least once, you write code that makes the test pass. One of the core tenets of Test Driven Development is that you write only enough code to make the test pass.
In addition to the aforementioned benefits of writing your tests backwards, Test Driven Development provides other benefits. Like we mentioned before, thinking about how you’ll test your code is a key part of building effective software. As a developer, one of your roles is to write software that’s easy to verify. You don’t want to ship code only to find out later that it doesn’t work. Catching defects early saves time and money.
With TDD, thinking about how you’ll test your code is a core part of the code-writing process. You’re writing the tests for your code while you write your code. If you’re an experienced developer, you’ve probably experienced writing a big chunk of code. You’re pretty sure it works, but as you lean back, you have no idea how to guarantee that the code you wrote works the way you expect. With Test Driven Development, that’s never a concern. You’re building your tests right into the process of writing the code itself.
Another benefit of Test Driven Development is that you write less code. Remember before how we talked about writing just enough code to make the test pass? That’s a key part of the Test Driven Development philosophy. As a developer, your job is to take your feature requests and turn them into testable features. Then, you write the tests for those features and finally the code that satisfies those tests. As we’ve said before, the key is to just write the code that satisfies those requests.
The benefit here is that writing just the code that satisfies the tests means you write fewer bugs. Why? Well, the argument goes, developers are prone to writing more code than they actually need at any given time. I know that I’m guilty of this. I’ll often try to build a more robust, complex solution than the current problem calls for. These robust solutions often lie dormant, because we’re not using all their features. They’ll be useful “someday.” In reality, that code is often never useful. That feature I thought was so important at the time turns out to never be needed. Or, by the time it’s useful, the parameters of that use have changed so that the code needs to be heavily modified before application.
This approach is an extreme variant of the “You Aren’t Gonna Need It” mentality. I know that as a developer, I regularly have to remind myself not to needlessly complicate my work by trying to solve future problems. Effectively adhering to Test Driven Development is a big benefit there.
Another major benefit to Test Driven Development is easier code refactoring. I’ve written enough code in my life to never expect that the work I do is permanent. I fully expect that every piece of code I ever write will be changed by someone down the line. It might be after I’m long gone, but it’ll happen, someday. When that day comes, I want to make it easy for that future teammate (or my future self!) to know how those changes break code that relies on mine. This is another benefit of the TDD philosophy. The tests that I write for my code serve as a form of documentation. It’s also a contract with other parts of the code base. So long as my code continues to pass all the tests I wrote for it, that code behaves the way the rest of the code expects.
So, if someone ever needs to refactor my code, they can do so confidently. The same is true if their refactoring breaks one of the tests. It might be that they need that test to change! It’s OK to refactor things and for those changes to break code. With a broad suite of unit tests, like those proscribed by TDD, you’ll know which behaviors of the code you’re changing. Then, as the person making those changes, it’s up to you to make sure you fix all the places that code is used.
Test Driven Development is a powerful philosophy. Most developers that follow it truly write better code. But it’s not enough on its own to deliver bug-free software. You’ll need to add more skills to your testing tool belt to deliver the best software that you can.
That’s where a tool like Prefix comes in. Prefix works best in test-driven teams. It runs on your local machine, and works like a web-request profiler. But it’s really powerful: it provides a lot more insight than an average profiler. It’s also really easy to read and understand the data it shows you. This means that if you’re working with one of the languages it supports, like Java and C#, you’ll find more bugs more quickly. You’ll also quickly identify bottlenecks in your code that are killing your performance. Even the best unit tests can’t tell you why or where your code is slow. Using Prefix will give you visibility into your code that you can’t get from tests alone.
Test Driven Development isn’t for everyone. I’ll be honest: I don’t use it for every piece of code that I write. But I do find the lessons it teaches to be valuable in writing better, clearer, bug-free code. It’s a good idea for every developer to give Test Driven Development a try, for at least a little while in their career. You’ll learn how to build better tests, and how to trust those tests to write better code.
Is today the right day for you to take your first steps into Test Driven Development? I don’t see why not!
If you would like to be a guest contributor to the Stackify blog please reach out to [email protected]