You might be surprised that there are some downsides to unit testing. Not to worry, the pros still outweigh the cons in most cases, and we will examine that closer.
When I talk about unit testing, I don’t mean the type that is designed to manipulate a coverage tool to show a high percentage of coverage and not much else. That is possible and I have experienced pressure to do this when clients have a clause in their software contract about unit testing coverage levels.
The type of testing I’m talking about prioritizes creating tests aimed at trying to discover edge-case and other hard-to-reproduce bugs that might not be discovered just during normal QA and manual regression testing. Having a high percentage of coverage is still important, but the fact is, in any large system there exist large amounts of non-critical code where it’s not as important to thoroughly test them.
- Greater confidence in refactoring/implementing new features
- The greatest fear for developers being assigned to work on new features/changes is introducing new bugs and breaking existing functionality. This is especially true for the inexperienced or if you are just being introduced to a massive codebase. Having an equally massive set of working and thoughtful unit tests gives you a lot of confidence in making changes and allows newer devs to get up to speed quicker.
- Possibility of discovering edge-case bugs
- QA/acceptance testing is great and can uncover a lot of bugs, but there is some class of bugs that are very unlikely to occur during normal use. Unit tests designed to test every edge-case, no matter how unlikely, can uncover these. If your tests are really good, specifically designed, and are executed often, you even have a good chance of uncovering threading/concurrency issues.
- Remove the need for manual regression testing
- This type of testing is usually a waste of time and unreliable. The more unit tests you have, the more you can free up these resources to do other things like writing automated tests.
- A slower pace of development overall
- Generally, when you need to implement new features or make significant changes to existing features, it can be done much faster without writing unit tests. If it’s complex functionality, writing thoughtful and thorough tests can double or triple the development time.
- Slower and more difficult to do refactoring
- When you have a large codebase including an equally large amount of unit tests, it’s going to make it more difficult and time-consuming to make changes. In addition to changing all of the execution code, you have to change all of the associated tests. It could just be to fix syntax errors, but usually, it would also involve changing tests completely as they may no longer make sense.
- Slower build times
- Ideally, most of your tests will be very fast. But the reality you will have thousands of tests in a large real-world project, most of which need to execute DB transactions. Even using an in-memory database, this will take up a lot of time when you build your project. Probably leading to you turning off tests.
When to use unit testing
If you are working on a codebase that is mature with several clients, or even if you are on the cusp of getting your first clients and nearing a very stable set of features, you should use it. And if you have no unit testing, you should start as soon as possible.
It’s critical to start unit testing when having fewer bugs becomes more important than the speed of development. Or more specifically when the pros outweigh the cons.
The longer you put this off, the more likely it is that you will never have unit testing.
When to avoid it
If you are starting out with little or no code, you should by all means avoid it. Even if you have a lot of code, but are still trying to get your first clients and need to rapidly develop new features for demos/RFP’s and such, you should still avoid it. You will probably end up throwing out a lot, if not all of your code during a re-write anyway.
The problem is when you have ignored unit testing for many years and clients/management have gotten used to not dealing with the cons mentioned above, it’s very hard to make the switch. It’s hard to explain and justify the increased timelines to clients, especially when they have gotten used to a certain pace of development.