What’s the point of unit testing? Why is it important? Even if you’ve never heard the question asked in so many words, you’ve probably been in a situation where your team ignored unit tests or treated them as an afterthought. They’re often the first thing to go when time runs short.
So, is unit testing important? How critical can it be if so many teams think it’s okay to ignore it? Well, the fact is unit testing is crucial to a development team’s success. Neglecting it can result in lost time, wasted effort, and missed opportunities.
We already debunked the most common excuses for not using tests and TDD. We know that we should write unit tests. Just like we know we should brush our teeth after every meal, exercise every day, and spend less time on social media. But is unit testing important?
Let’s take a look at why unit testing isn’t just important but is also critical to development success.
Unit Tests Are Documentation
For most developers, the fastest way to learn how to use new code is by reading an example. Documentation is useful, but nothing beats an example. This is especially true for a unit test, which is sample code that you can run in your IDE. What’s the first thing you scan for when you’re reading documentation? I bet it’s code snippets.
What’s the first thing you look for when you browse through the source code? Tests. What could be more useful than a collection of working unit tests? They’re examples of the code in use. They’re easy to run, and you can copy or change them for experimentation.
Is there anything more frightening than source code that doesn’t come with any tests at all? If you’re inheriting it from another developer, having no unit tests is downright terrifying. Production code and sample programs often have external dependencies and may not run in a development environment. Even if you can run them outside of production, experimenting with them can be difficult too. You can run unit tests in place, in your development environment, or on the command line, and they are easy to play with.
Unit Tests Catch Regressions
How do you know when a code fix or new feature doesn’t break existing behavior? Hopefully, your answer is unit tests. Useful unit tests establish baseline behavior for your code in isolation. By running them as part of each build, you catch unforeseen side effects before you release the code into the wild.
Detecting code regressions early in the development process is the most recognized practical application of unit tests. But the benefits of testing go beyond catching problems early; tests help you isolate problems quickly, too. By providing feedback right away, they make it easier to correlate changes to bugs.
Unit Tests Provide Immediate Feedback
How long do you want to wait before you see your code work? After you deploy it to QA? With unit tests, you don’t have to wait at all. Feedback is precisely one build away. It’s impossible to overstate the importance of the tight feedback loop unit testing offers developers.
As I mentioned above, immediate feedback simplifies troubleshooting. Rather than trying to find a new regression after the fact via log messages or a description of the problem, bugs surface immediately and can be correlated directly to the last code change. If you’re already accustomed to running frequent builds, it’s possible to isolate a new issue in minutes.
But this immediate feedback isn’t just for isolating problems. It’s also useful for confirming new behavior too. Developers aren’t lawyers, and we spend a lot of time asking questions we don’t already know the answers to. Unit tests give us the rapid responses we need. This tight feedback process saves time and improves our code.
Unit Tests Improve Code Quality
What’s the best way to figure out how to design your code? By using it.
Translating use cases and requirements into software is only the first step in the development process. It’s only after writing tests that you can use the new code to solve problems so you know you have a usable product. (Of course, inverting the process by writing the tests first is even better.) It’s not uncommon to find that an interface or object is hard to use or that you missed a set of features entirely in your first pass at developing a product. Unit tests shorten this discovery process. Designing and implementing tests makes you your own first customer. In a way, unit tests create a second type of feedback: how does this code look? Is it easy to use? Does it solve the problems it’s supposed to solve?
Depending on how you work, you may write your tests after you’ve implemented your code. After you think you are feature complete or at some other natural break point, you create tests that verify critical aspects of the code’s behavior. You might decide that something is shaped wrong, and you may change a method signature or some names to make things more transparent to a user.
Or, you might start with a test that defines what you want the code to do, and then write code that passes the test. Yes, I am referring to test-driven development (TDD.) Kent Beck says that TDD “gives you a chance to learn all of the lessons that the code has to teach you.” When you put tests up front, you write software that you understand better. By virtue of writing tests up front, you’ve already used your own software once.
Unit Tests Build Confidence
There’s a common thread to this list of reasons why unit tests are important. In each case, units tests build confidence about your code. Unit tests ask questions, and the answers provide assurances about the reliability and quality of your software throughout its lifecycle.
Code that includes unit tests comes with an implied guarantee. You can rely on the behavior they verify. If you make changes to the code and the tests still pass, you can be confident that you haven’t broken anything.
Developing tests as you write your application code builds confidence too. Whether you’re using TDD or not (and you should), unit tests are a stake in the ground for how the software behaves. The immediate feedback that your unit tests provide reassures you that you are headed in the right direction. Checking in code with working tests makes the rest of your team feel better too.
When it comes time to take your code off the shelf and update, repair, or change it, a test suite offers confidence too. You can pick up where the last developer left off, in a tight code-test-repeat development cycle. You can catch new regressions as you work and add tests to an existing set of verifications.
So, why is unit testing important? Think about what you give up without them. Without tests, you don’t get that tight feedback loop as you work. You have to wait for QA and integration testing to see your application in action. Simply put, if you don’t develop with unit tests, you can’t be completely confident that your code is ready for release.