4 naming conventions to better name your tests

Cesar Aguirre - May 3 '21 - - Dev Community

I originally posted an extended version of this post on my blog a couple of weeks ago. It's part of a series I've been publishing, called Unit Testing 101

These are 4 common naming conventions we can use to write better names for our tests.

Let's use Stringie, a (fictional) library to manipulate strings. Stringie has a Remove() method to remove a substring from the beginning or the end of an input string.

string transformed = "Hello, world!".Remove("Hello");
// ", world!"

string transformed = "Hello, world! Again, Hello".Remove("Hello").From(The.End);
// "Hello, world! Again, "
Enter fullscreen mode Exit fullscreen mode

Also, when Remove() receives no parameters, it returns empty. It removes all characters from the input string.

string transformed = "Hello, world!".Remove();
// ""
Enter fullscreen mode Exit fullscreen mode

Now, let's see the 4 naming conventions.

1. UnitOfWork_Scenario_ExpectedResult

[TestClass]
public class RemoveTests
{
    [TestMethod]
    public void Remove_NoParameters_ReturnsEmpty() {}

    [TestMethod]
    public void Remove_ASubstring_RemovesOnlyASubstring() {}
}
Enter fullscreen mode Exit fullscreen mode

This convention uses underscores to separate the unit of work or entry point of out test, the scenario under test 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".

2. Plain English sentence

[TestClass]
public class RemoveTests
{
    [TestMethod]
    public void Returns_empty_with_no_parameters() {}

    [TestMethod]
    public void Removes_only_a_substring() {}
}
Enter fullscreen mode Exit fullscreen mode

This convention strives for a less rigid name structure using sentences in plain English. For more readability, it uses underscores to separate each word.

This convention considers smells adding method names and filler words like "should" or "should be" in our test names. For more readability, it uses underscores to separate each word.

3. Sentence from classes and methods names

[TestClass]
public class RemoveGivenASubstring
{
    [TestMethod]
    public void RemovesThatSubstring() {}

    [TestMethod]
    public void RemovesThatSubstringFromTheEnd() {}
}
Enter fullscreen mode Exit fullscreen mode

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.

With this convention, we can read our test names like full sentences joining the class and method names. Like this: "Remove, given a substring, removes that substring".

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() {}
    }
}
Enter fullscreen mode Exit fullscreen mode

This last convention uses sentences splitted into class and method names too. But, each scenario has its own nested class. Notice, we create a nested class GivenASubstring inside a RemoveTests class.

Voilà! That's how we can name our unit tests. Naming things is hard, I know. Your mission, Jim, should you choose to accept it, is to write better names.

Upgrade your unit testing skills with my course: Mastering C# Unit Testing with Real-world Examples on Udemy. Practice with hands-on exercises and learn best practices by refactoring real-world unit tests.

Happy testing!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .