#6: Common Arguments Against Unit Tests
Happy Monday! Welcome back to The Coder Cafe! This week, we will explore the theme of unit tests. To kick things off, let’s discuss why unit tests are essential.
Here are nine common arguments against unit tests and how we should address them:
1. The code is too simple to need tests
Even simple code may have unexpected bugs or edge cases. Also, what if the code evolves? It may not always stay simple. And how can we factually define when code is too simple anyway? If the code is truly simple, then writing tests should be quick and easy, making it even more worthwhile.
2. I will add tests later
In many cases, we won’t. It’s much easier to write unit tests when the code is fresh in our minds. Delaying tests shows a problematic misunderstanding of their true value. We shouldn’t see them as a constraint but rather as a benefit. Tests are a strategic investment in the long-term health of our systems.
3. Testing is for testers
No, testing is not only for testers. As developers, we need to make sure our code works before it’s passed to other stages of testing.
I once worked on a project where the development team believed their responsibility was solely to craft features, leaving all testing to the QA team. We were only doing minimal testing. Eventually, the team ended up with more testers than developers—a clear sign that something was very wrong. Every test failure was taking much more time to fix than it would have if we had proper unit tests in place; it was an absolute mess.
4. We will catch issues during integration tests
While integration tests are important, they are not a substitute for unit tests. Integration tests typically focus on nominal cases and can't cover all edge cases. They also take longer to run and can be flaky. Addressing issues during integration testing is usually much more time-consuming and harder to diagnose than unit tests.
5. This code is just temporary, so it doesn’t need tests
Temporary code has a way of becoming permanent. Even if the code is truly temporary, it can still cause significant issues if it breaks. Writing unit tests ensures that the code behaves as expected during its temporary use and helps avoid disruptions, especially if the code ends up sticking around longer than planned.
6. I don’t have time to write unit tests
This is a false economy—another clear sign that we don’t really understand the value of unit tests. Skipping unit tests might seem like a time-saver, but it often leads to greater problems later. Again, bugs found during later stages of development are much more expensive and time-consuming to fix.
7. This code didn’t have unit tests, so why start now?
It’s never too late to start writing unit tests. Using the absence of tests as an excuse is actually the opposite of what we should be doing. Our mindset should be: let’s leave the codebase in a better shape than we found it. This doesn’t mean repaying all the testing debt at once, but at the very least, it’s our responsibility to ensure that any changes we make are properly tested. Meanwhile, starting with unit tests now can establish a new standard of quality and set a positive precedent for the rest of the codebase.
8. This project is just a PoC; it won’t go into production
While the project may be intended as just a Proof of Concept (PoC), there's always a chance it could go into production—and even faster than we can imagine. I once took this approach on a PoC, only writing a minimal amount of unit tests for the implemented features. At some point, I got the signal that the company wanted to ship it to production, and suddenly, I needed much more time than anticipated. Adding tests revealed that my code wasn’t working as well as I thought, which led me to a complete redesign.
It’s OK not to put the same level of testing effort into a PoC; however, we should still maintain decent test coverage to ensure our code is correct and to avoid unpleasant surprises if the project moves forward—or at least, we should communicate clearly and upfront that if the PoC has to be shipped, it will require a complete rewrite1.
9. It’s just a cleanup, no need to add tests
Cleanups are prime opportunities to improve tests as well. Making changes without tests increases the risk of introducing regressions or new bugs.
However, not every cleanup change needs a new test or a test update—especially if our unit tests are well-designed and focus on behavior, not implementation2.
Any other arguments you have already heard at your work? Let me know in the comments.
Tomorrow, we will explore key properties of effective unit tests.
Which I didn’t do.
We will cover this (absolutely) crucial testing topic in a future issue.