Question

General

  • Follow the same standards for all tests.
  • Be clear about what each test state is.
  • Be specific about the expected behavior.

Examples

1) MethodName_StateUnderTest_ExpectedBehavior

Public void Sum_NegativeNumberAs1stParam_ExceptionThrown() 

Public void Sum_NegativeNumberAs2ndParam_ExceptionThrown () 

Public void Sum_simpleValues_Calculated ()

Source: Naming standards for Unit Tests

2) Separating Each Word By Underscore

Public void Sum_Negative_Number_As_1st_Param_Exception_Thrown() 

Public void Sum_Negative_Number_As_2nd_Param_Exception_Thrown () 

Public void Sum_Simple_Values_Calculated ()

Other

  • End method names with Test
  • Start method names with class name
Was it helpful?

Solution

I am pretty much with you on this one man. The naming conventions you have used are:

  • Clear about what each test state is.
  • Specific about the expected behaviour.

What more do you need from a test name?

Contrary to Ray's answer I don't think the Test prefix is necessary. It's test code, we know that. If you need to do this to identify the code, then you have bigger problems, your test code should not be mixed up with your production code.

As for length and use of underscore, its test code, who the hell cares? Only you and your team will see it, so long as it is readable, and clear about what the test is doing, carry on! :)

That said, I am still quite new to testing and blogging my adventures with it :)

OTHER TIPS

This is also worth a read: Structuring Unit Tests

The structure has a test class per class being tested. That’s not so unusual. But what was unusual to me was that he had a nested class for each method being tested.

e.g.

using Xunit;

public class TitleizerFacts
{
    public class TheTitleizerMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void Name_AppendsTitle()
        {
            // Test code
        }
    }

    public class TheKnightifyMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void MaleNames_AppendsSir()
        {
            // Test code
        }

        [Fact]
        public void FemaleNames_AppendsDame()
        {
            // Test code
        }
    }
}

And here is why:

Well for one thing, it’s a nice way to keep tests organized. All the tests (or facts) for a method are grouped together. For example, if you use the CTRL+M, CTRL+O shortcut to collapse method bodies, you can easily scan your tests and read them like a spec for your code.

I also like this approach:

MethodName_StateUnderTest_ExpectedBehavior

So perhaps adjust to:

StateUnderTest_ExpectedBehavior

Because each test will already be in a nested class

I tend to use the convention of MethodName_DoesWhat_WhenTheseConditions so for example:

Sum_ThrowsException_WhenNegativeNumberAs1stParam

However, what I do see a lot is to make the test name follow the unit testing structure of

  • Arrange
  • Act
  • Assert

Which also follows the BDD / Gherkin syntax of:

  • Given
  • When
  • Then

which would be to name the test in the manner of: UnderTheseTestConditions_WhenIDoThis_ThenIGetThis

so to your example:

WhenNegativeNumberAs1stParam_Sum_ThrowsAnException

However I do much prefer putting the method name being tested first, because then the tests can be arranged alphabetically, or appear alphabetically sorted in the member dropdown box in VisStudio, and all the tests for 1 method are grouped together.


In any case, I like separating the major sections of the test name with underscores, as opposed to every word, because I think it makes it easier to read and get the point of the test across.

In other words, I like: Sum_ThrowsException_WhenNegativeNumberAs1stParam better than Sum_Throws_Exception_When_Negative_Number_As_1st_Param.

I do name my test methods like other methods using "PascalCasing" without any underscores or separators. I leave the postfix Test for the method out, cause it adds no value. That the method is a test method is indicated by the attribute TestMethod.

[TestMethod]
public void CanCountAllItems() {
  // Test the total count of items in collection.
}

Due to the fact that each Test class should only test one other class i leave the name of the class out of the method name. The name of the class that contains the test methods is named like the class under test with the postfix "Tests".

[TestClass]
public class SuperCollectionTests(){
    // Any test methods that test the class SuperCollection
}

For methods that test for exceptions or actions that are not possible, i prefix the test method with the word Cannot.

[TestMethod]
[ExpectedException(typeOf(ArgumentException))]
public void CannotAddSameObjectAgain() {
  // Cannot add the same object again to the collection.
}

My naming convension are base on the article "TDD Tips: Test Naming Conventions & Guidelines" of Bryan Cook. I found this article very helpful.

The first set of names is more readable to me, since the CamelCasing separates words and the underbars separate parts of the naming scheme.

I also tend to include "Test" somewhere, either in the function name or the enclosing namespace or class.

As long as you follow a single practice, it doesn't really matter. Generally, I write a single unit test for a method that covers all the variations for a method (I have simple methods;) and then write more complex sets of tests for methods that require it. My naming structure is thus usually test (a holdover from JUnit 3).

I use a 'T' prefix for test namespaces, classes and methods.

I try to be neat and create folders that replicate the namespaces, then create a tests folder or separate project for the tests and replicate the production structure for the basic tests:

AProj
   Objects
      AnObj
         AProp
   Misc
      Functions
         AFunc
   Tests
      TObjects
         TAnObj
            TAnObjsAreEqualUnderCondition
      TMisc
         TFunctions
            TFuncBehavesUnderCondition

I can easily see that something is a test, I know exactly what original code it pertains to, (if you can't work that out, then the test is too convoluted anyway).

It looks just like the interfaces naming convention, (I mean, you don't get confused with things starting with 'I', nor will you with 'T').

It's easy to just compile with or without the tests.

It's good in theory anyway, and works pretty well for small projects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top