When I asked my mailing list “What keeps you from writing unit tests?” one person said “I just don’t really understand the value of them.” And it wasn’t just that person — the majority of responses fit into that category. Generally speaking, iOS developers don’t write unit tests because they don’t know what the benefits are.
Let’s look at all the benefits you can get from following the practice of unit testing.
1. Your company will save money
When you write unit tests, you catch bugs earlier — much earlier than if you test manually — because you can test small units of functionality before all the components are built. This enables you to fix bugs faster since the code you just wrote is still fresh in your mind. And fixing bugs faster saves your company money. Some developers told me their company doesn’t want to pay them to spend extra time writing tests, but if your company knew the total project cost would be lower, wouldn’t they be delighted to have you do it?
Andy Hunt and Dave Thomas explain why testing matters in their seminal book, The Pragmatic Programmer (emphasis mine):
“A good project may well have more test code than production code. The time it takes to produce this test code is worth the effort. It ends up being much cheaper in the long run.”
And in Bad Testing Practices, Luis Solano says, “[Testing] reduces the time of creating software…by allowing you to modify your code faster, with the confidence that your tests will tell you when something went wrong.”
Trust the experts: unit testing will save your company money since you’ll be able to catch bugs sooner and fix them faster.
2. Your users will be happier
Even if you write a very simple unit test that verifies that your LoginViewController has the right title, you now have confidence that your code meets that requirement. And if you get your tests to run every time you commit code with continuous integration (CI), you can be sure that your LoginViewController will always have the right title as long as your unit test passes.
Granted, this is small and may seem like it’ll never fail. But that test will be quick to write, and even on a short project it’ll be executed thousands of times in the life of your project. Every time it passes you can be sure that part of the application still works, ensuring you didn’t accidentally change it in the process of doing something else. This enables you to ship stable updates to your users, knowing that some baseline functionality still works.
One reader pointed out that “an incomplete unit test suite can lull you into thinking you have captured all error conditions.” And they’re right — you won’t be able to unit test every single requirement, no matter how many tests you have. But having some unit tests and a good CI server gives you confidence that the part of your code that’s tested still works correctly every time you commit. When your users get app updates, they’ll be happy that the features they depend on still work they way they’re supposed to.
3. You’ll be more confident when you refactor
If you have unit tests that verify the requirements, you can refactor your implementation without worrying about breaking anything. As long as your tests continue to pass, you can be sure your code continues to meet those requirements.
More wisdom from The Pragmatic Programmer (emphasis mine):
“Make sure you have good tests before you begin refactoring. Run the tests as often as possible. That way you will know quickly if your changes have broken anything. […] [Martin] Fowler’s point of maintaining good regression tests is the key to refactoring with confidence.”
Remember that unit tests aren’t just to catch bugs now as you’re developing new features; they’ll serve as your regression tests later to ensure your app continues to work well in the future.
You don’t have to feel anxious every time you need to refactor your code, worrying whether you’ll break a feature that works. Set yourself up with a good suite of unit tests so you can refactor with confidence, knowing your code still works the way it should.
4. You’ll have up-to-date documentation for your code
Since you write unit tests by translating requirements into code, unit tests are a form of documentation for your app. But unlike written requirements or design mockups, they can be executed and will tell you whether the implementation meets the requirements or not. Plus, documentation that’s written as unit tests must stay up to date — if it happened to become outdated, the unit tests would fail.
In unit tests, you can see how to instantiate classes, what sort of setup they need, and what you can expect when you call methods on them.
Greg Veres wrote in and described how unit tests have served as documentation on his projects (emphasis mine):
“When you write unit tests with good names, you are effectively documenting the behaviour of the code you have just written. And since you are testing requirements, you are effectively documenting the requirements the code is implementing. So when you come back in 6 months, you can quickly read through the list of unit tests and remind yourself what the code must do, then you can look in the code to remind you how it implements those requirements.”
Having your requirements documented in unit tests makes it clear what your app needs to do in order to continue working the way you expect. And when you forget how something is supposed to work, you can look back at your tests to find out.
Unit testing will give you a whole bunch of benefits; it’ll save your company money, make your users happier, give you confidence when you refactor, and help you understand your code better. You may also find that testing helps you focus on what you need to get done, release more frequently, and help you work more easily with legacy code, as others have found.
I hope you’re ready to start getting these benefits by unit testing your app. In the next article, you’ll learn what framework to use and how to write your first tests. Don’t miss out! Enter your name and email in the boxes to be sure you get it.