How to name your unit tests: Four test naming conventions
12 Apr 2021 #tutorial #csharpFrom our previous post, we learned about four common mistakes we make when writing our first unit tests. One of them is not to follow a naming convention. Let’s see four naming conventions for our unit tests.
Test names should tell the scenario under test and the expected result. Writing long names is acceptable since test names should show the purpose behind what they’re testing. When writing tests, prefer good test names over assertion messages.
These are four common naming conventions we can use. Let’s continue to use Stringie, a (fictional) library to manipulate strings. Stringie has a Remove()
method to remove a substring from the beginning or end of an input string.
1. UnitOfWork_Scenario_ExpectedResult
[TestClass]
public class RemoveTests
{
[TestMethod]
public void Remove_NoParameters_ReturnsEmpty() {}
[TestMethod]
public void Remove_ASubstring_RemovesOnlyASubstring() {}
}
We find this naming convention in the book The Art of Unit Testing. This convention uses underscores to separate the unit of work or entry point, the test scenario, and the expected behavior.
With this convention, we can read our test names out loud like this: “When calling Remove with no parameters, then it returns empty.”
Grab a free copy of my ebook Unit Testing 101: From Zero to Your First Tests on my Gumroad page. I include these four naming conventions and three more chapters to help you start writing your first unit tests in C#.
2. Plain English sentence
[TestClass]
public class RemoveTests
{
[TestMethod]
public void Returns_empty_with_no_parameters() {}
[TestMethod]
public void Removes_only_a_substring() {}
}
Unlike the “UnitOfWork_Scenario_ExpectedResult” convention, this convention strives for a less rigid name structure.
This convention uses sentences in plain English for test names. We describe in a sentence what we’re testing in a language easy to understand, even for non-programmers. For more readability, we separate each word in our sentence with underscores.
This convention considers smells adding method names and filler words like “should” or “should be” in our test names. For example, instead of writing, “should_remove_only_a_substring”, we should write “removes_only_a_substring”.
You could read more about this convention in Vladimir Khorikov’s post: You are naming your tests wrong!.
3. A sentence from classes and methods names
[TestClass]
public class RemoveGivenASubstring
{
[TestMethod]
public void RemovesThatSubstring() {}
[TestMethod]
public void RemovesThatSubstringFromTheEnd() {}
}
This naming convention uses sentences in plain English too. In this case, class names will act as the subject of our sentences and method names as the verb and the complement. We write units of work or entry points in class names and expected results in method names.
Also, we can split different scenarios into separate classes. In the class names, we add the keyword Given
followed by the scenario under test.
For our Remove()
method, we can name our test class RemoveGivenASubstring
and our test methods RemovesOnlyASubstring
and RemovesSubstringFromTheEnd
.
With this convention, we can read our test names like complete sentences in the “Test Explorer” menu in Visual Studio when we group our tests by class. Like this: “Remove, given a substring, removes that substring.”
You can read more about this convention in ardalis’ post: Unit Test Naming Convention.
4. Nested classes and methods
[TestClass]
public class RemoveTests
{
[TestMethod]
public void ReturnsEmpty() {}
[TestClass]
public class GivenASubstring
{
[TestMethod]
public void RemovesThatSubstring() {}
[TestMethod]
public void RemovesThatSubstringFromTheEnd() {}
}
}
This last convention uses sentences split into class and method names too. Unlike the previous naming convention, each scenario has its own nested class.
For example, instead of having a test class RemoveGivenASubstring
, we create a nested class GivenASubstring
inside a RemoveTests
class.
You can learn more about this last convention in Kevlin Henney’s presentation Structure and Interpretation of Test Cases on YouTube.
Voilà! That’s how we can name our unit tests. Remember naming things is hard. Pick one of these four naming conventions and stick to it. But, if you inherit a codebase, prefer the convention already in use. I hope you can write more readable test names after reading this post.
If you want to practice naming unit tests, check my Unit Testing 101 repository. There you will find the test names that Stringie developers wrote. Your mission, Jim, should you choose to accept it, is to write better names.
If you’re new to unit testing, read my post on how to write your first unit tests in C# and check the 4 common mistakes when writing your first tests. Don’t miss the rest of my Unit Testing 101 series where I also cover mocking, assertions, and other best practices.
Happy testing!