617

What are the best practices for naming unit test classes and test methods?

This was discussed on SO before, at What are some popular naming conventions for Unit Tests?

I don't know if this is a very good approach, but currently in my testing projects, I have one-to-one mappings between each production class and a test class, e.g. Product and ProductTest.

In my test classes I then have methods with the names of the methods I am testing, an underscore, and then the situation and what I expect to happen, e.g. Save_ShouldThrowExceptionWithNullName().

Community
  • 1
  • 1
James Newton-King
  • 44,416
  • 22
  • 106
  • 128
  • 1
    See here: http://stackoverflow.com/questions/96297/naming-conventions-for-unit-tests – Forgotten Semicolon Sep 30 '08 at 22:48
  • 2
    This does not answer your question, but worth a read: http://haacked.com/archive/2012/01/02/structuring-unit-tests.aspx – Robs Jan 10 '12 at 21:46
  • 6
    Google style guide says: `test_`, e.g. `testPop_emptyStack` https://google-styleguide.googlecode.com/svn/trunk/javaguide.html 5.2.3 Method names. When in doubt, follow Google. – Ciro Santilli新疆棉花TRUMP BAN BAD Jan 28 '15 at 15:28
  • 4
    @CiroSantilli六四事件法轮功包卓轩 And the next sentence says: "There is no One Correct Way to name test methods". Go figure. – user2418306 Jan 17 '16 at 03:29
  • _Google Java Style Guide_ is now here: https://google.github.io/styleguide/javaguide.html. Search for "test". – Voicu Sep 10 '18 at 13:54
  • 2
    I still prefer Phil Haack's [recommendation](https://haacked.com/archive/2012/01/02/structuring-unit-tests.aspx/) even years later. – pim Sep 17 '18 at 19:06
  • This might interest some of you. If you happen to use XUnit I wrote a package [AutoName.xUnit](https://github.com/benscabbia/AutoName.xUnit) that will convert any defined test name to a plain old English sentence i.e. `MyTestName` will be displayed as `My Test Name` – benscabbia Jan 24 '19 at 20:49
  • 1
    https://dzone.com/articles/7-popular-unit-test-naming lists the pros and cons of several popular methods. e.g. @CiroSantilli新疆棉花TRUMPBANBAD's Google recommendation has the con that "if method names change as part of code refactoring than [sic] test name like this should also change or it becomes difficult to comprehend at a later stage". – Leponzo Apr 21 '21 at 14:46

12 Answers12

574

I like Roy Osherove's naming strategy. It's the following:

[UnitOfWork_StateUnderTest_ExpectedBehavior]

It has every information needed on the method name and in a structured manner.

The unit of work can be as small as a single method, a class, or as large as multiple classes. It should represent all the things that are to be tested in this test case and are under control.

For assemblies, I use the typical .Tests ending, which I think is quite widespread and the same for classes (ending with Tests):

[NameOfTheClassUnderTestTests]

Previously, I used Fixture as suffix instead of Tests, but I think the latter is more common, then I changed the naming strategy.

Pang
  • 8,605
  • 144
  • 77
  • 113
Marc Climent
  • 9,006
  • 2
  • 47
  • 54
  • 253
    For me it makes no sense to put method name in test method. What if You rename method? No refactoring tool will rename tests for You. Eventually You end up renaming test methods by hand or more likely having wrongly named tests. It's like with comments. To much is worse then not commenting code at all. – Piotr Perak May 29 '11 at 05:41
  • 4
    @Peri: Very insightful. The same issue occurs with the class name. Hypothetically it would be possible to put tests in a private nested class simply named "Test" but no unit test framework supports this, and most programmers resist shipping unit test code. I once wrote a unit test to reflect over all unit tests and assert they are named correctly, but have lost that code. – Jay Bazuzi Aug 03 '11 at 04:07
  • 91
    @Peri, I think it is a tradeoff. On one hand your test names may become outdated, on the other hand you can't tell what method your test is testing. I find the latter comes up much more often. – Joel McBeth Apr 19 '12 at 19:23
  • 16
    To add to Peri's comment - all methods are responsible for some action, e.g `UpdateManager.Update()`. Having this in mind I tend to call my tests `WhenUpdating_State_Behaviour` or `WhenUpdating_Behaviour_State`. This way I test a particular action of a class while avoiding to put a method name in a test name. But the most important thing is that I have to have a clue what business logic is failing when I see a name of a failing test – Ramunas Oct 25 '12 at 06:19
  • 9
    Resharper and IntelliJ both would probably find your test method and offer to rename it for you if you refactored/renamed using those tools. The also try to look in comments where you mention the method name and update those too. – Jeff Martin Dec 06 '12 at 14:50
  • 2
    @Ramunas: I agree with you. Instead of method name, which can potentially change, using the action that you wish to test as part of the test name is very logical. – Skadoosh Dec 07 '12 at 21:01
  • 2
    I actually clicked the link and there is a deviation from this answer and the suggested use. It should be `[UnitOfWork_StateUnderTest_ExpectedBehavior]` which does *not* require the method name. – atconway Mar 22 '13 at 13:42
  • 68
    Good method names often are the same as the action the method perfoms. **If you have to decide** between naming your test after your method or the action the method performs **that may be a hint you should rename your method**. (Not in every case though) – Kaadzia Sep 19 '13 at 09:04
  • 2
    @Peri - on the contrary, it makes sense to include the method name in a test name (when you are testing an individual method - and you often are) because, that is what the test is testing. It is descriptive and helpful to those reading the test suite. Yes, it couples the test name to the method name, but renaming tests is trivial and low-risk. Including the name of the method under test in the test name simply reflects the high cohesion between the test name and the name of the method under test. – Ben Aston Feb 09 '14 at 00:25
  • 4
    @Ben - I disagree. Method name is least important in test. You test functionality. Renaming tests is as easy as updating comments :) Yet people don't do it! That's why comments suck too! – Piotr Perak Feb 09 '14 at 19:58
  • @Peri Decoupling test name from anything other than functionality is ideal. Benefits include lower maintenance o'head, shorter test names & avoidance of 1 class of misleading test name. Experience informs me however when working in a team tests are often highly imperfect. Identification of test elements e.g. arr./act/assert can be tough. In addition, test naming is usually poor (even with native speakers) & often downright misleading. Hence I favor the naming convention in this ans. that forces the writer to think clearly about the unit under test & that reduces reader time-to-understanding. – Ben Aston Feb 09 '14 at 22:25
  • 2
    @Ben I think it's far superior to teach your teams write good tests then to use worse naming convention because your team writes bad tests. And I don't accept arrange/act/assert comments in tests. If you need them that means your test sucks. That's my opinion. – Piotr Perak Feb 09 '14 at 23:36
  • 3
    A method name in UnitTest looks noisy. Why not write a unit test that looks like a business logic statement! For example, one of my test method is as follows: "The_sum_of_all_probabilities_for_a_set_of_events_must_equal_to_1(). So, the unit test class should be full of business logic statements. And we write unit test to cover all business logic. Why care which method is performing the task as long as all business logic is covered. You should have your class with very limited responsibility anyway (single responsibility principle) so it wont be hard to find out which method is covering what. – Emran Hussain Aug 23 '15 at 23:11
  • @PiotrPerak , what alternative you propose then? I am also not a fan of having method names in test method name because of refactoring issues. But I still would like to be able to trace it back to the method under test somehow, maybe with a reference or anything else. Do you have any suggestion? – PiJei Mar 24 '19 at 09:49
  • 3
    @PiJei my test names state the facts about system under test (SUT). It plays nicely with Xunit which has [Fact] attribute instead of [Test]. So for example for StringCalculator tests could be named Calculates_sum, Adds_numbers, or Throws_for_negative_numbers. It doesn't matter that method is called Sum(), Calculate() or AddNumbers(). And if I rename it facts about my SUT are still valid so I don't need to rename tests. – Piotr Perak Mar 25 '19 at 12:28
  • @MarcCliment why the method name should start with a capital case, In java, we use the first letter of the method as small case? – Ashutosh Chamoli Mar 16 '20 at 05:55
  • @AshutoshChamoli The examples were made with a C# mindset but if in your language of choice is more idiomatic to start with lowercase, just do it. In the same way, ending the library name in .Tests is .NET specific, other languages and environments may have other conventions on how to group the tests. – Marc Climent Mar 16 '20 at 09:51
  • @MarcCliment Yes understood. I was asking this question, because I am aware of the standard practice that first letter of method being small case, but I am not sure about the successive words in the same method. Some people use them in capital case even in Java, I feel they should also be small case like `should_increase_balance_when_deposit_is_made` rather than `should_Increase_Balance_When_Deposit_Is_Made`, though not aware about the standard for this in Java. – Ashutosh Chamoli Mar 17 '20 at 05:36
  • I tend to agree with @PiotrPerak: I don't see any benefit from putting method name in a test method. Testing the behavior might involve several methods. – Artur Beljajev Mar 15 '21 at 14:36
144

I like to follow the "Should" naming standard for tests while naming the test fixture after the unit under test (i.e. the class).

To illustrate (using C# and NUnit):

[TestFixture]
public class BankAccountTests
{
  [Test]
  public void Should_Increase_Balance_When_Deposit_Is_Made()
  {
     var bankAccount = new BankAccount();
     bankAccount.Deposit(100);
     Assert.That(bankAccount.Balance, Is.EqualTo(100));
  }
}

Why "Should"?

I find that it forces the test writers to name the test with a sentence along the lines of "Should [be in some state] [after/before/when] [action takes place]"

Yes, writing "Should" everywhere does get a bit repetitive, but as I said it forces writers to think in the correct way (so can be good for novices). Plus it generally results in a readable English test name.

Update:

I've noticed that Jimmy Bogard is also a fan of 'should' and even has a unit test library called Should.

Update (4 years later...)

For those interested, my approach to naming tests has evolved over the years. One of the issues with the Should pattern I describe above as its not easy to know at a glance which method is under test. For OOP I think it makes more sense to start the test name with the method under test. For a well designed class this should result in readable test method names. I now use a format similar to <method>_Should<expected>_When<condition>. Obviously depending on the context you may want to substitute the Should/When verbs for something more appropriate. Example: Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()

Community
  • 1
  • 1
Jack Ukleja
  • 12,190
  • 10
  • 65
  • 101
  • 44
    Maybe even better and less redundant, just write a sentence that tells what it does, assuming the test works: `increasesBalanceWhenDepositIsMade()`. – hotshot309 Feb 09 '12 at 22:17
  • 3
    Recently saw an article that mentioned a similar naming convention (wish I'd bookmarked it). Designed to make the lists of tests very readable when sorted by test fixture. You see something like "BankAccount" then under it (on different lines) "Should_Increase_Balance_When_Deposit_Is_Made" "Should_Decrease_Balance_When_Withdrawal_Is_Made", etc. Reads very like a specification, which is sort of what TDD is all about. – Simon Tewsi Jan 22 '13 at 00:00
  • Found the article. It's in Justin Etheredge's CodeThinked blog [Beginning Mocking With Moq 3 – Part 1](http://www.codethinked.com/Beginning-Mocking-With-Moq-3-Part-1). – Simon Tewsi Jan 22 '13 at 00:48
  • You may want to take a look at this http://www.fluentassertions.com/ – Akira Yamamoto Oct 27 '14 at 12:04
  • 13
    I also use Should and When but the other way round. e.g. WhenCustomerDoesNotExist_ShouldThrowException(). To me this makes a lot more sense than Should then When (i.e in a certain scenario there should be a certain expected outcome). This also fits in with AAA (Arrange, Act, Assert)...the Assert is at the end...not the beginning ;-) – bytedev Apr 15 '15 at 14:38
  • See also: http://ardalis.com/unit-test-naming-convention Note that it's a good idea to put Should as a suffix on the class name so that the class name doesn't match the SUT name. I also tend to have one test class per method these days, with folders per type being tested, in which case the folder names are often FooTests (instead of Foo) again to avoid naming collisions. – ssmith Dec 01 '16 at 21:01
  • 2
    @Schneider : considering "should" = "recommended" then optional, I wonder: would not it be lexicaly better to use "shall" = "must" then required/mandatory. For example, RFCs makes the difference between both. So having tests pass is recommended or required? – blackwizard Jun 07 '17 at 08:51
  • Assuming that Money is a valuetype. I think atleast the signature should be contained in the Deposit test method in this case Deposit(Money amount) you should be making a Deposit(Money amount, Money initialBalance, Money expectedBalance) and setup some testCases. Including negative zero and fractional numbers (especially those that fail on floating point precision). To cover a lot more than just one value. – Wouter Jul 30 '20 at 17:25
86

I like this naming style:

OrdersShouldBeCreated();
OrdersWithNoProductsShouldFail();

and so on. It makes really clear to a non-tester what the problem is.

Sklivvz
  • 28,698
  • 24
  • 111
  • 164
  • 64
    but @hotshot309, he may be using .NET - [.NET Capitalization Conventions](http://msdn.microsoft.com/en-us/library/ms229043.aspx) – Ace Mar 09 '12 at 15:21
  • 2
    @Ace, I totally agree with you and noticed this about a minute after I posted this comment. I swore that I deleted it when I saw my mistake, but somehow, I guess I didn't. Sorry about that. – hotshot309 Mar 13 '12 at 16:08
  • then why not seperate that with underscores, you're using the same pattern as Roy O. – PositiveGuy Oct 24 '13 at 06:16
  • 3
    @CoffeeAddict because underscores within identifiers are an aberration not really idiomatic in C# – Sklivvz Oct 24 '13 at 10:10
  • 2
    I also like to avoid the usage of `should` I will prefer `will` so `OrdersWithNoProductsWillFail()` – Calin Feb 13 '15 at 10:08
  • 1
    I dont like this naming convention. For example: "OrdersShouldBeCreated" has no real detail about the scenario (arrangment) under which the orders would be created. What if there are multiple scenarios and therefore multiple tests? You cant have the same test method name... – bytedev Mar 30 '16 at 15:53
  • 1
    You'd use it for the general case. For other scenarios, you'd have a more specific name. – Sklivvz Mar 30 '16 at 16:06
  • 6
    @Calin In my opinion using `Will` isn't really *appropriate* and by doing so you're actually mistakenly telling the reader that in no way **the test** will fail... if you use `Will` to express something in the future that might not happen you're using it incorrectly whereas `Should` is the better choice here because it indicates that you want/wish something to happen but it didn't or couldn't, when the test runs it tells you whether it failed/succeeded so you can't really imply that beforehand, that's the logical explanation to it, what's yours? why do you avoid `Should`? – Eyal Alon Oct 10 '16 at 04:24
55

Kent Beck suggests:

  • One test fixture per 'unit' (class of your program). Test fixtures are classes themselves. The test fixture name should be:

    [name of your 'unit']Tests
    
  • Test cases (the test fixture methods) have names like:

    test[feature being tested]
    

For example, having the following class:

class Person {
    int calculateAge() { ... }

    // other methods and properties
}

A test fixture would be:

class PersonTests {

    testAgeCalculationWithNoBirthDate() { ... }

    // or

    testCalculateAge() { ... }
}
marc_s
  • 675,133
  • 158
  • 1,253
  • 1,388
Sergio Acosta
  • 11,109
  • 12
  • 58
  • 89
  • 5
    I wish more people would follow these guidelines. Not too long ago I had to rename more than 20 test methods because they had names like "ATest", "BasicTest", or "ErrorTest". – Wedge Sep 30 '08 at 23:44
  • 90
    doesn't the method prefix of 'test' become redundant given the class's suffix? – Gavin Miller Jan 05 '09 at 21:12
  • I would like to add the compatibility to TestDox. http://agiledox.sourceforge.net/ – guerda Apr 07 '09 at 06:07
  • 55
    Remember that when Kent wrote that book. Attributes was not invented. Therefore the name Test in the method name indicated to the test framework that the method was a test. Also alot have happend since 2002. – Thomas Jespersen May 15 '10 at 16:04
  • 14
    testCalculateAge... this is a meaningless name for your test method. "test" is redundant (do you name all your methods with "method" prefix?). The rest of the name has no condition under test or what was expected. Is CalculateAge the method under test?.....who knows... – bytedev Feb 27 '13 at 14:02
  • 1
    I'd like to add that when using this strategy, documentation is required to specify the expected output. As a side note about the 'test' prefix; some unit testing frameworks require specific prefixes or suffixes to recognize the tests. Prefixing abstract classes with 'Abstract' is not considered redundant (because it's self documenting), so why doesn't the same apply with 'Test'? – siebz0r Aug 03 '13 at 08:44
  • 1
    @ThomasJespersen true, but doesn't make criticism less valid now. It's no longer necessary to use the prefix. – Blorgbeard Jan 03 '14 at 06:21
18

Class Names. For test fixture names, I find that "Test" is quite common in the ubiquitous language of many domains. For example, in an engineering domain: StressTest, and in a cosmetics domain: SkinTest. Sorry to disagree with Kent, but using "Test" in my test fixtures (StressTestTest?) is confusing.

"Unit" is also used a lot in domains. E.g. MeasurementUnit. Is a class called MeasurementUnitTest a test of "Measurement" or "MeasurementUnit"?

Therefore I like to use the "Qa" prefix for all my test classes. E.g. QaSkinTest and QaMeasurementUnit. It is never confused with domain objects, and using a prefix rather than a suffix means that all the test fixtures live together visually (useful if you have fakes or other support classes in your test project)

Namespaces. I work in C# and I keep my test classes in the same namespace as the class they are testing. It is more convenient than having separate test namespaces. Of course, the test classes are in a different project.

Test method names. I like to name my methods WhenXXX_ExpectYYY. It makes the precondition clear, and helps with automated documentation (a la TestDox). This is similar to the advice on the Google testing blog, but with more separation of preconditions and expectations. For example:

WhenDivisorIsNonZero_ExpectDivisionResult
WhenDivisorIsZero_ExpectError
WhenInventoryIsBelowOrderQty_ExpectBackOrder
WhenInventoryIsAboveOrderQty_ExpectReducedInventory
grundoon
  • 225
  • 2
  • 3
  • you talked about test method names and test fixture names. test fixture names are mapped to production classes. where do you write the production method name in your test? – The Light May 28 '11 at 17:23
13

I use Given-When-Then concept. Take a look at this short article http://cakebaker.42dh.com/2009/05/28/given-when-then/. Article describes this concept in terms of BDD, but you can use it in TDD as well without any changes.

Pashec
  • 22,491
  • 3
  • 23
  • 26
  • Given-When-Then is the same as MethodName_Scenario_ExpectedBehavior, isn't it?! – The Light May 28 '11 at 17:26
  • 2
    Not exactly. Given_When_Then refers more to: GivenAnEntity_WhenSomeActionHappens_ThatResultIsExpected The test should express the will to test a **behavior not an implementation**. – plog17 Oct 21 '15 at 12:13
  • 1
    "Given When Then" is often refered to as Gherkin. Its a DSL that came out of the Cucumber, JBehave and Behat tools. – bytedev Mar 30 '16 at 15:48
  • +1 this is the best method imo. Decoupling how a method does something from what you expect the result to be is very powerful and avoids a lot of problems described in other comments. – Lee Jan 16 '19 at 14:40
  • Is it something like this? `GivenLoggedIn_WhenWritingArticle_ThenShowSuccessMessage` – wonsuc Oct 19 '20 at 05:42
9

I recently came up with the following convention for naming my tests, their classes and containing projects in order to maximize their descriptivenes:

Lets say I am testing the Settings class in a project in the MyApp.Serialization namespace.

First I will create a test project with the MyApp.Serialization.Tests namespace.

Within this project and of course the namespace I will create a class called IfSettings (saved as IfSettings.cs).

Lets say I am testing the SaveStrings() method. -> I will name the test CanSaveStrings().

When I run this test it will show the following heading:

MyApp.Serialization.Tests.IfSettings.CanSaveStrings

I think this tells me very well, what it is testing.

Of course it is usefull that in English the noun "Tests" is the same as the verb "tests".

There is no limit to your creativity in naming the tests, so that we get full sentence headings for them.

Usually the Test names will have to start with a verb.

Examples include:

  • Detects (e.g. DetectsInvalidUserInput)
  • Throws (e.g. ThrowsOnNotFound)
  • Will (e.g. WillCloseTheDatabaseAfterTheTransaction)

etc.

Another option is to use "that" instead of "if".

The latter saves me keystrokes though and describes more exactly what I am doing, since I don't know, that the tested behavior is present, but am testing if it is.

[Edit]

After using above naming convention for a little longer now, I have found, that the If prefix can be confusing, when working with interfaces. It just so happens, that the testing class IfSerializer.cs looks very similar to the interface ISerializer.cs in the "Open Files Tab". This can get very annoying when switching back and forth between the tests, the class being tested and its interface. As a result I would now choose That over If as a prefix.

Additionally I now use - only for methods in my test classes as it is not considered best practice anywhere else - the "_" to separate words in my test method names as in:

[Test] public void detects_invalid_User_Input()

I find this to be easier to read.

[End Edit]

I hope this spawns some more ideas, since I consider naming tests of great importance as it can save you a lot of time that would otherwise have been spent trying to understand what the tests are doing (e.g. after resuming a project after an extended hiatus).

Asotos
  • 668
  • 9
  • 13
Thorsten Lorenz
  • 11,293
  • 6
  • 48
  • 58
9

See: http://googletesting.blogspot.com/2007/02/tott-naming-unit-tests-responsibly.html

For test method names, I personally find using verbose and self-documented names very useful (alongside Javadoc comments that further explain what the test is doing).

Ates Goral
  • 126,894
  • 24
  • 129
  • 188
7

I think one of the most important things is be consistent in your naming convention (and agree it with other members of your team). To many times I see loads of different conventions used in the same project.

bytedev
  • 5,800
  • 3
  • 33
  • 43
2

In VS + NUnit I usually create folders in my project to group functional tests together. Then I create unit test fixture classes and name them after the type of functionality I'm testing. The [Test] methods are named along the lines of Can_add_user_to_domain:

- MyUnitTestProject   
  + FTPServerTests <- Folder
   + UserManagerTests <- Test Fixture Class
     - Can_add_user_to_domain  <- Test methods
     - Can_delete_user_from_domain
     - Can_reset_password
Kev
  • 112,868
  • 50
  • 288
  • 373
2

I should add that the keeping your tests in the same package but in a parallel directory to the source being tested eliminates the bloat of the code once your ready to deploy it without having to do a bunch of exclude patterns.

I personally like the best practices described in "JUnit Pocket Guide" ... it's hard to beat a book written by the co-author of JUnit!

lesmana
  • 22,750
  • 8
  • 73
  • 83
Steve Moyer
  • 5,487
  • 20
  • 31
  • 3
    Don't believe this actually answers the question at hand - could you make an edit and refrence JUnit Pocket Guide? Thanks! – Nate-Wilkins Apr 17 '14 at 15:54
0

the name of the the test case for class Foo should be FooTestCase or something like it (FooIntegrationTestCase or FooAcceptanceTestCase) - since it is a test case. see http://xunitpatterns.com/ for some standard naming conventions like test, test case, test fixture, test method, etc.