Effective Testing - Use Descriptive Test Names
Picking good test names can help us identify what’s wrong with our code when something fails.
It’s Friday afternoon. You finally finished that long refactor you’ve been working on for the whole week. Everything is looking good. Except you run the tests and see one failure.
🤔
Unfortunately, you can’t really tell what’s broken from looking at that output. You’ll have to browse the test code to identify the failure.
But what if the output looked more like this:
Now the issue is obvious. You can immediately tell which part of the code is not working and what the output should be.
Test names are the first (and often only) piece of information we see about a test. Using a descriptive test name can help us identify what’s broken at a glance. Furthermore, it helps us keep the test focused on validating one specific behavior, discouraging us from inflating the test with other unrelated assertions.
How
Instead of just using the name of the method being tested, try focusing on the behavior you want to validate. Describe the state of the system, the action performed, and the expected output. More often than not, you’ll end up with a huge name, something you probably wouldn’t use on production code, but that’s ok.
If you’re using Kotlin, you can use backticks to have whitespaces in your function name. If you’re working with JUnit you can leverage the @DisplayName
annotation for prettier names. You can even get emojis in there:
You can also write a custom name generator using @DisplayNameGeneration
as shown here.
Some testing libraries like Kotest, also support nesting tests:
You can read more about test naming in Chapter 12 of Software Engineering at Google.
This post is part of the Effective Testing Series.