Member-only story
Advanced Unit Tests: 5 Pitfalls and How To Avoid Them
Not all unit tests are equal; some might be harmful

Unit tests exist to give you confidence that your software is working as expected, even as the software changes over time.
I have written a lot of tests, and I have read much more. The majority of them helped me to discover bugs early, provided documentation, and prevented regressions. But I also found some tests that failed to do any of that. Instead, they were either so complex you could not figure out what they were testing, would fail at random, or even never fail at all.
This article presents five pitfalls that lead to ineffective unit tests, and how you can fix them.
1. Write One Unit Test per Function
It seems very straightforward. Let’s say you have a small function that does one thing. Let’s say it’s called calculate_average
. It is one small unit, it is what unit testing best practices want you to test. So you write a test for it, test_calculate_average
.
What is wrong with this? It tests a single unit of code, but it should test for a single behavior of the test. Often this is also phrased as having a single assertion in a test. A much better test would be test_calculate_average_return_0_for_empty_list
. Once you have a couple of them, they give you detailed documentation for free.
It also changes your mindset on how to write tests. You have to think about the different behaviors that you expect from a function. Before you know it, you are thinking about the edge cases, and even writing tests for them.
“Write one unit test per unit of functionality, not unit of code.”
I once helped a colleague debug a problem: Our scrubbing logger was not properly scrubbing data. They were suspecting it wouldn’t scrub additional key-value pairs properly. As I wrote that code some time ago I had no idea whether that theory was correct. But I knew I wrote ample tests, and I quickly found one documenting the behavior in question: scrubbing_logger_scrubs_extra_key_values
! We could quickly discard our initial assumption and save some valuable time.