3 Most Important Parts of the Best Unit Test Names

July 7, 2015

How many times have you run your tests, gotten a failure, and had to go digging through the test code to try to understand what it’s complaining about? For many of you, you’re so used to doing this that you don’t even notice it’s a problem.

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:

  1. What is being tested
  2. Under what circumstances
  3. What is the expected result

Roy Osherove, author of The Art of Unit Testing, provides a good unit test naming convention that incorporates these three elements. In his blog post “Naming standards for unit tests” he describes it thus:

UnitOfWork_StateUnderTest_ExpectedBehavior

I have adopted this 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:

testMethodName_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.

Pick a naming convention that works for you

Whatever naming convention you choose, try to communicate the three parts. It may feel overly verbose, but there’s nothing wrong with having really long test names, as long as they’re clear.

How do you like to name your tests? Can you find any poorly named tests in your suite? Click here to share in the comments.

Jon Reid

Posts Twitter Facebook Google+

I've been practicing Test Driven Development (TDD) since 2001. Learn more on my About page.

4 responses to 3 Most Important Parts of the Best Unit Test Names

  1. Another really great benefit of clear test method names: If you ever have to port your app to another platform, you can tell very quickly which tests are platform-specific and can be ignored, vs. which tests are business-logic centric and should be reused.

  2. This is great advice for the younglings out there. I tend to do use this same methodology, albeit indirectly because I generally lean toward the BDD style testing frameworks like Kiwi, Specta and Quick/Nimble. They somewhat force you into answering the 3 parts by having a spec name (what are we testing), some context (what is the state the object under test is in) and the assertion (something should be true about this object). Each of the parts then builds up into a readable test name in the runner so that when a test breaks you already have a fairly detail test name giving you more information regarding the failure. Anyhow, carry on!

  3. I’m with Saul on this one.
    Which is to say I completely agree with you, Jon, that this attention to naming is crucial. In fact I take a considerable portion of my conference talks on my own test framework driving the same point home.

    So the fact that you have to fight XCTest so much to achieve such an important thing is, to me, a bit of a smell. As Saul points out there are other frameworks out there that are much better tuned to this sort of thing (I could add my framework, Catch, to his list – which supports Objective-C). Unless your hands are tied I would recommend considering one of those frameworks.

    For a taste. take a look at this (getting old now) blog post of mine: http://www.levelofindirection.com/journal/2013/6/28/catch-10.html under the heading, “On your best behaviour”.

  4. Thanks for this great advice, Jon. I have started to use this naming scheme and it feels better now.

    About the BDD frameworks. I tried BDD and realized that this style of testing isn’t suited for me. I still think to technical during the test creation and often already have an idea how I could implement the feature. I know this isn’t the way to go. I still have to learn.

    And I’m always at the bleeding edge (Swift 2.0, iOS 9, …) and to often I had to wait for frameworks to catch up.