Unit test coding standards

by EpsilonVector   Last Updated November 03, 2017 14:05 PM

Usually when talking about coding standards we refer to the code of the program itself, but what about the unit tests? Are there certain coding standards guidelines that are unique to unit tests? What are they?



Answers 7


Off the top of my head, I can think of three differences in coding style for test code.

In naming test methods, I follow the pattern of shouldDoSomethingWhenSomeConditionHolds.

Inside the test, it is customary to follow the following spacing pattern:

@Test
shouldReturnAccountBalenceWhenGetBalenceIsCalled() {
    // Some lines 
    // of setup code
    // go here.

    // The action being tested happens after a blank line.

    // An assertion follows another blank line.
}

Some insist on only one assertion per test, but this is far from universal.

The DRY (Don't Repeat Yourself) is less of a consideration in test code than in production code. While some repeated code should be placed in a setUp method or a testUtils class, striving for zero repetition in test code will lead to tightly coupled and inflexible tests, which discourages refactoring.

Eric Wilson
Eric Wilson
October 31, 2010 18:33 PM

Roy Osherove recommends the following pattern for naming your tests:

NameOfMethodUnderTest_StateUnderTest_ExpectedBehavior() 

See http://weblogs.asp.net/rosherove/archive/2005/04/03/TestNamingStandards.aspx

Robert Harvey
Robert Harvey
October 31, 2010 18:53 PM

The main thing is to remember that unit tests are essentially mini-specifications. This means that the emphasis must always be on readability.

Firstly, this means that names must clearly communicate what is under test and what is being asserted.

Secondly though, which is sometimes forgotten, is that as specifications they should be doing just that - specifying behaviour. That is, unit tests should not contain logic - or potentially they fall into the trap of repeating the program's functionality rather than testing it.

Sometimes the tests will involve objects which are complex to set up, you should strive to keep this set up logic separate from your tests using something like an object mother or a test data builder.

I'll just round off with a few book recommendations:

xUnit Test Patterns: Refactoring Test Code: Excellent book, some say it's a bit dry but I don't think so. Goes into a lot of detail about lots of different ways of organising tests and how to keep them maintainable. Relevant if you're using something like NUnit etc.

The Art of Unit Testing: With Examples in .Net: The best book on the nitty-gritty of writing and maintaining tests. Despite being really new I find the mocking sections a little dated already as AAA syntax is now pretty standard rather than just another way of doing it.

Growing Object-Oriented Software, Guided by Tests: This book is just amazing! By far the best unit testing book and the only advanced one which puts unit testing as a first class citizen in the design process. Was reading this when it was a public beta and been recommending since. Excellent real-worldish worked example used throughout the book. Would recommend reading Roy's book first though.

FinnNk
FinnNk
October 31, 2010 18:55 PM

Don't put logic in your unit tests. For example, let's say you're testing an add method, you could have something like this:

void MyTest_SaysHello()
{
   string name = "Bob";
   string expected = string.Format("Hello, {0}", name);
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello(name);
   Assert.AreEqual(expected, actual);
}

In this particular case, you're likely repeating the same logic as what's in the test, so you're essentially testing "1 + 1 == 1 + 1", rather than "1 + 1 == 2", which is the "real" test. So what you would really want your test code to look like is:

void MyTest_SaysHello()
{
   string expected = string.Format("Hello, Bob");
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello("Bob");
   Assert.AreEqual(expected, actual);
}
Hugo
Hugo
October 31, 2010 19:37 PM

Somewhat similar to what Farmboy has already mentioned, My method name format

 <MethodName>Should<actionPerformed>When<Condition>

e.g

 GetBalanceShouldReturnAccountBalance() {
Amit Wadhwa
Amit Wadhwa
November 01, 2010 02:58 AM

Long, descriptive method names. Remember, test methods are never called from code (they're called by the unit test runner that discovers and calls them via reflection), so it's OK to go crazy and have method names 50-80 characters long. Specific naming convention (camel-case, underscores, "should", "must", "when", "given", etc.) is not really important as long as the name answers three questions:

  • what is under test?
  • what are the conditions?
  • what is the expected result?

Test methods should be short.

Test methods should have a simple, linear structure. No if or loop constructs.

Test methods should follow the "arrange-act-assert" pattern.

Each test should test one thing. This usually means one assert per test. A test like { Do A; Assert B; Assert C; } should be refactored into two: { Do A; Assert B; } and { Do A; Assert C; }

Avoid random data or things like 'DateTime.Now'

Ensure that all test fixture members are returned to their original state at the end of the test (e.g. using a teardown)

Even if you remove duplication ruthlessly in your production code, code duplication in test fixtures is a much smaller concern.

azheglov
azheglov
March 07, 2011 22:51 PM

This blog post provides a pretty thorough summary of guidelines to follow for unit testing:

http://tekprolixity.blogspot.com/2012/04/unit-testing-guidelines.html.

Tell me what you think.

Neil Sareen
Neil Sareen
April 23, 2012 00:07 AM

Related Questions




Python unit testing coding standard

Updated August 23, 2016 08:03 AM


Standards used to implement an Android application?

Updated April 04, 2017 04:05 AM