They say that naming is one of the hardest problems in software engineering. Well, perhaps. It’s at least one of the most common hurdles we need to clear.
The naming of test methods might not have the same potential for disaster as naming public APIs, but if you’re a developer who’s been thrown into an existing codebase, having good test names can help you make sense of things and when your tests fail, they can help direct your next steps.
Pick a core naming convention
For JUnit units tests, I typically use the following test naming convention:
There’s a few different conventions out there and there is merit in looking at some alternatives. My advice is not so much about this convention but about getting the most out of whatever convention you choose to adopt.
Let’s have a look at some potential misuses of this convention and how we can make them better!
Class under test
Let’s imagine we want to unit test this
The implementation details don’t really matter too much, so I’ve left them out.
I’ll start by staying that at the very least your test name should be factually correct. If you’re in a hurry and copying and pasting tests around, you might neglect to change a clause in the test name, making it inconsistent with what the test is actually doing. Don’t do that. Take the time to read your test names and their implemetation.
In this case the “should” clause doesn’t add any value. It’s a test, of course we want to verify that it returns the correct value. That’s the entire point of having a test!
To be more informative, we should describe what the correct value is.
Focus on the unit
For unit tests, the test names should remain relevant to the unit under test. It’s tempting to include context that hint how the unit is used in practice, but these can often get out of date or just be confusing to someone without a full picture of the system behaviour.
In this case, we shouldn’t mention that the articles have been synced into the store, because the class under test doesn’t support syncing only storing. It may be true that in our app, where the articles are synced into the store, but it’s not true of the
ArticleStore in isolation.
Save that extra context for your integration tests.
Keep your terminology consistent
Similarly; avoid using synonyms for important terminology or actions. If you class defines that you “store”
Articles, then don’t refer to them as being “added”
So rather than:
Don’t just repeat the method signature
This name is another case of “technically true, but not actually useful”. We can see from the
getArticles return type that it should return a
What is more useful is to say what we expect the contents of that
List to be: which is all the
Articles that have been stored.
You can probably guess, this one.
Don’t mention irrelevant details
How the outcome is achieved through mocking or other similar details shouldn’t be reflected in the test name. In this case, it is somewhat relevant that the
Articles, but not that the
ArticleFetcher is mocked, so long as the
ArticleStore should behave the same way regardless.
To be honest, that’s a bit of an indirect mouthful, so:
JUnit 5 gives you the ability to define the test name, in a more readable way, separately from the test method using the
I’d like to be proven wrong, but this just seems like you would have two naming problems - one for the test method and the other for the display name. You’d also have to maintain them both too.
Perhaps it could be useful if you wanted to make your test case report look like you written the tests in Kotlin.
Speaking of which!
Kotlin gives you even more language freedom to define the test name in a more human-readable way by avoiding camel and snake case ugliness.
Still, you should decline the invitation to write an essay for a test name; try to keep your core naming structure intact.
`fetchArticles returns all Articles returned by the ArticleFetcher`
Just like perfection is the enemy of good, sometimes overly strict naming rules get in the way of writing good names. You’ll need to find a test name writing style that suits your team and the tests and be prepared to revisit it. You will discover that there are certain tests that are more easily described in one way than another. Perhaps you find one style of language is for whatever subjective reason, sits better with the team.
The situation you want to avoid is where the test name is an unhelpful description of the intention of the test. Help out your team and your future self and write considered and considerate test names.
Thanks for reading!
This post is Creative Commons Attribution 4.0 International (CC BY 4.0) licensed.