← All Talks

How to Write Better Test Names

Artem Zakharchenko
Artem Zakharchenko

There is no great test without a great test name. Here are five tips to help you name your test cases in JavaScript.

  1. Start with a verb: A test is there to check how something works. So, start its name with a verb. This is one of the simplest ways to introduce consistency to your test names.

//❌ Tests validate behaviors.
// Behaviors are actions, actions are verbs!
it("homepage");
it("greeting message");
// ✅ Starting with a verb sets the rest
// of the test name on the right path.
it("navigates to the homepage");
it("displays the greeting message");

  1. Use subject-less third person: In other words, imagine there is "it" before the test name. So, it becomes "fetches the user by ID," "displays the greeting message." Not only will the test names read more naturally this way, but it will also improve their consistency and predictability across the entire code base.

//🧐 This is a stylistic tip.
it("fetch the user by id");
it("display the greeting message");
// ✅ Following this tip helps you stay
// consistent in your naming and allows
// to disambiguate between nouns and verbs
it("fetches the user by id");
it("displays the greeting message");

  1. Omit implied verbs: Verbs like "tests," "should," "must," "asserts," and "validates" bring no value to the test name because they're implied. Instead, focus on what it is the test is doing. "Navigates to the homepage," "displays the greeting message," "validates the request headers." This way, you can reduce the visual clutter of the test name and help the test focus on what matters – the intention behind the system.

// ❌ Omit verbs like "tests", "should",
// "must", "checks", etc. Those are implied.
it("tests the homepage");
it("should display the greeting message");
it("must validate the request headers");
// ✅ Focus on what the system does.
it("navigates to the homepage");
it("displays the greeting message");
it("validates the request headers");

  1. Describe the intention, not the implementation: I know it may be tempting to put a lot of technical details into the test name. It may even seem useful sometimes, but it's not. Those details bring no value to the test name. They only harm the test.

// ❌ Implementation details have no place in tests,
// and that includes the test names.
it("performs a GET request to the /user endpoint");
// ✅ Focus on WHAT the system does, not HOW.
it("fetches the user");

  1. Keep it short: Long sentences can be really great to convey a lot of information, to give a lot of detail and context, but it's not what you want from your test name. Neither is it what you want from your test. You really want it to be focused on one particular thing, one behavior.

In fact, if you have a really long test name, perhaps that's an indication that this test does way too much and should be split in multiple smaller tests.


// ❌ Watch out for phrases and flavors
// that bring little value to the test name.
it("redirects the user back to the product detail page");
// ✅ Rephrase, remove repetition, and utilize
// domain-specific terms to keep test names short.
// e.g. PDP = product detail page
it("redirects to the PDP");

Transcript

00:00 There is no great test without a great test name. Here are five tips to help you name your test cases in JavaScript. Tip number one. Start with a verb. A test is there to check how something works. So start its name with a verb. This is one of the simplest ways to introduce consistency to your test names. Tip number two. Use subject-less third person.

00:19 In other words, imagine there is it before the test name. So it becomes fetches the user by ID, displays the greeting message. Not only will the test names read more naturally this way, it will improve their consistency and predictability across the entire code base. Tip number three. Omit implied verbs.

00:37 Verbs like tests, should, must, asserts, validates bring no value to the test name because they're implied. Instead, focus on what it is the test is doing. Navigates to the homepage, displays the greeting message, validates the request headers.

00:54 This way you can reduce the visual clutter of the test name and help the test focus on what matters, the intention behind the system. Which brings me to the next tip. Tip number four. Describe the intention, not the implementation. I know it may be tempting to put a lot of technical details into the test name. It may even seem useful sometimes, but it's not.

01:13 Those details bring no value to the test name. They only harm the test. Take a look at this one. So this test is named performs to get request to the slash user in point. It makes extremely clear what the code it tests actually does. But consider what happens if some of these details change. What if the end point changes?

01:33 So suddenly, the test name becomes out of sync with the actual thing it's testing. This is a redundant dependency that you don't have to maintain and introduce in the first place. Instead, if you focus your test name on what the code here does, what is the intention behind that code, it simply becomes fetches the user. It's both concise and clear.

01:53 Remember that implementations may change, but intentions stay the same. Finally, tip number five. Keep it short. Long sentences can be really great to convey a lot of information, to give a lot of detail and context, but it's not what you want from your test name. Neither is it what you want from your test. You really want it to be focused on one particular thing, one behavior.

02:12 In fact, if you have a really long test name, perhaps that's an indication that this test does way too much and should be split in multiple smaller tests. There are a couple of things that can help you keep the test name short. Omitting the implied verbs and focusing the names on the intention is already a great start.

02:28 You can also use rephrasing because some concepts can be represented in much shorter terms. Like here, instead of writing redirects the user back, you can just write redirects and lose no meaning. In a similar fashion, sentences like has no items in the current cart can just become has an empty cart.

02:45 Sometimes you can even utilize domain-specific language to substitute for longer terms. Like here, the product detail page can just become PDP for short. Just make sure that everybody on the team is aware of those terms so they're not confusing. Keeping a glossary page can help a lot with that. And finally, you can utilize the context.

03:02 So if you have a bunch of tests that have repetitive phrases in the names, like here, two tests concern themselves with authentication using GitHub, well, we can move this test into a separate file and drop this context from the names because it's implied now on the file level.