The benefits of unit testing
Unit testing is all the rage now. It seems like you can't read about programming these days without seeing it at least mentioned. But what's so great about unit testing, anyway?
When I first started using unit testing extensively, I programmed mostly in C++ and Visual Basic, using Visual Studio and the VB6/Office VBA development environments. Setting up unit testing in those environments was somewhat painful. It also seemed to me that writing unit tests would slow down development.
I eventually found that it was well worth the initial pain to set up unit testing, and that unit testing actually allows me to develop more reliable code faster. In this article, I want to describe the benefits that I've seen from unit testing:
- Code is more modular/easier to reuse
- Code is easier to change/maintain
- Development is faster (!)
- Built-in sample uses
I'll describe each of these benefits in detail below.
Code is more modular/easier to reuse
In order to write good unit tests, you've got to ruthlessly eliminate code dependencies. You can't write unit tests when you have to fire up the program's GUI for every test. You need to eliminate or parameterize dependencies so you can test code in isolation, or provide mock/fake objects when that's not possible.
Modularizing your code like this has the side benefit of making it easier to reuse. Say for example that your program writes reports. Currently you only need to write reports in HTML format. But in order to test your report writer, you modularize it and eliminate dependencies. That'll make it easier to reuse your code when you have to add support for XML, or MS Excel, or some other type of format in the next version.
Code is easier to change/maintain
When you don't have unit tests in place, modifying existing code can be scary. You don't know what you might break. So you read the code very carefully, looking for dependencies, and run the code through the debugger several times, making sure everything looks good. And then you hope for the best…
The picture's a lot different when you have unit tests in place. Firstly, your unit tests are more likely to catch errors when you break things, because they make sure all the assumptions you've made about your code so far still hold.
Secondly, your code already has fewer dependencies because you had to reduce coupling in order to make your code testable. Therefore, there are fewer things that can go wrong when you make changes — there's less "spooky action at a distance."
Development is faster
At first glance, it might seem that writing unit tests is actually making your development go slower. After all, writing tests takes time, time that you weren't spending before. But writing tests is faster than the typical code-and-debug cycle.
When you don't have unit tests, what's the typical coding cycle? If you're anything like I was, you set some breakpoints in the code you're developing, fire up the GUI, and perform some actions that'll make program execution hit your code. Then you step through it, and make sure everything works OK. If you're really diligent, then you do this a few times with different inputs.
It's a lot different with unit testing. You write some code and some tests (not necessarily in that order , then pow! You run your tests, and they take less than a minute to run. And then you're off coding again. No firing up the GUI, no typing values into text boxes.
I've found that the time you save from the code-and-debug cycle more than makes up for the time it takes to write unit tests.
Built-in sample uses
Unit tests are built-in examples of how to use your code. And unlike comments, unit tests never lie. If you write your unit tests like a story — for example, I create an entry, I retrieve an entry, I update an entry, I delete an entry — then you're telling future programmers (including the future you) how to use your code.
I hope I've been able to show the benefits of unit testing. If you're not using unit testing, I hope I've convinced you to consider it, and if you're considering it, I hope I've convinced you to give it a try!