Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I change the naming convention for my unit tests?

I currently use a simple convention for my unit tests. If I have a class named "EmployeeReader", I create a test class named "EmployeeReader.Tests. I then create all the tests for the class in the test class with names such as:

  • Reading_Valid_Employee_Data_Correctly_Generates_Employee_Object
  • Reading_Missing_Employee_Data_Throws_Invalid_Employee_ID_Exception

and so on.

I have recently been reading about a different type of naming convention used in BDD. I like the readability of this naming, to end up with a list of tests something like:

  • When_Reading_Valid_Employee (fixture)
    • Employee_Object_Is_Generated (method)
    • Employee_Has_Correct_ID (method)
  • When_Reading_Missing_Employee (fixture)
    • An_Invalid_Employee_ID_Exception_Is_Thrown (method)

and so on.

Has anybody used both styles of naming? Can you provide any advice, benefits, drawbacks, gotchas, etc. to help me decide whether to switch or not for my next project?

like image 689
BlackWasp Avatar asked Jun 19 '09 15:06

BlackWasp


People also ask

How should you name unit tests?

Naming your tests The name of your test should consist of three parts: The name of the method being tested. The scenario under which it's being tested. The expected behavior when the scenario is invoked.

What is an appropriate naming scheme for a test class?

Test class naming convention usually follows the naming convention of the class being tested, e.g., the class under test is “Order” the corresponding test class will be “OrderTests“. When in doubt, it is a good practice to model the test class name after the production class it is testing.

Which is the proper naming convention of a test case?

Test case names are usually limited to a specific length, so space is at a premium. Make sure to keep names unique while refraining from adding any details that aren't required for identification. You can add those details to the case's instructions or test data, for example.


4 Answers

The naming convention I've been using is:

functionName_shouldDoThis_whenThisIsTheSituation

For example, these would be some test names for a stack's 'pop' function

pop_shouldThrowEmptyStackException_whenTheStackIsEmpty

pop_shouldReturnTheObjectOnTheTopOfTheStack_whenThereIsAnObjectOnTheStack

like image 71
ampersandre Avatar answered Oct 10 '22 04:10

ampersandre


Your second example (having a fixture for each logical "task", rather than one for each class) has the advantage that you can have different SetUp and TearDown logic for each task, thus simplifying your individual test methods and making them more readable.

You don't need to settle on one or the other as a standard. We use a mixture of both, depending on how many different "tasks" we have to test for each class.

like image 21
Joe White Avatar answered Oct 10 '22 03:10

Joe White


I feel the second is better because it makes your unit tests more readable to others as long lines make the code look more difficult to read or make it more difficult to skim through. If you still feel there's any ambiguity as for what the test does, you can add comments to clarify this.

like image 30
mnuzzo Avatar answered Oct 10 '22 04:10

mnuzzo


Part of the reasoning behind the 2nd naming convention that you reference is that you are creating tests and behavioural specifications at the same time. You establish the context in which things are happening and what should actually then happen within that context. (In my experience, the observations/test-methods often start with "should_," so you get a standard "When_the_invoicing_system_is_told_to_email_the_client," "should_initiate_connection_to_mail_server" format.)

There are tools that will reflect over your test fixtures and output a nicely formatted html spec sheet, stripping out the underscores. You end up with human-readable documentation that is in sync with the actual code (as long as you keep your test coverage high and accurate).

Depending on the story/feature/subsystem on which you're working, these specifications can be shown to and understood by non-programmer stakeholders for verification and feedback, which is at the heart of agile and BDD in particular.

like image 25
Jay Avatar answered Oct 10 '22 04:10

Jay