Every time you have to read test code, precious time is lost. The feedback cycle lengthens, and you’re breaking your stride.
Remember, we are trying to go for fast feedback. When I run unit tests and get a failure, I want to understand what I just broke. And I want to do this without reading the test code.
Ideally, the test name alone gives me the information I need.
Poor test names
Consider a test named “testCalculateSalary”. Simple names like this are common in unit test tutorials, but I can’t recommend them in real code.
If this test fails, what do we know? We know that something has gone wrong in salary calculation. But beyond that, we can’t tell without looking.
- Which path through salary calculation failed?
- What type of employee was it?
- Was there anything unusual about the chosen date range?
So many questions we can’t answer without digging into the test code, and possibly the production code as well!
Good test names: three elements
Instead, let’s put more information into the test name. When a test fails, I want to know three things:
- What is being tested
- Under what circumstances
- What is the expected result
In his blog post “Naming standards for unit tests” he describes it like this:
UnitOfWork_StateUnderTest_ExpectedBehavior
I have adopted this unit test naming convention, with slight changes:
- XCTest lacks a way to annotate test methods. So we still have to start with a “test” prefix, followed by the “unit of work” part.
- I usually begin the “state under test” part with the prefix “with”.
- I usually begin the “expected behavior” part with the prefix “should”.
All told, I apply Roy Osherove’s template to yield test names that look like this:
test_methodName_withCertainState_shouldDoSomething
It may look odd to combine camel casing with underscores. Though unusual, I like how the underscores clearly separate the test name into its three components.
My test names don’t follow this template slavishly. If the unit of work is obvious (from the name of the test class), I may omit it. If the expected behavior is obvious, I may omit it. But whether explicit or implied, the three elements must be present without guesswork.