BDD Test Naming Experiment

September 8th, 2008

Of course, I am not the first person to do this, but gosh, isn’t it cool?

This is the test suite from a project I am working on and I decided to move the BDD naming convention into the syntax:
(class name) + (method name) = behavioral sentence

This library has 100% code coverage and tests the sad path pretty well, in my opinion.

Click the image to get a bigger view.

Click the image to get a bigger view.

What’s your opinion? Is this easy to read to understand intent? Does this document my code for the next developer? Or is it just too much?

  • Jan Van Ryswyck
  • http://www.elegantcode.com Jarod

    I think its a good start. The tests are still very ‘code’ like in nature, focused on the objects themselves (Employee, Repo, EmailAddress).

    The idea with BDD – Specification Context is that we want to take it to the ‘Behavior’ level. Following a good naming convention will force you to drive the behavior out. This is where is gets confusing as the ideas are fairly new. There are a lot of camps here as far as naming and structuring tests goes. The Given\When\Then, Because\It, When\Should.

    I prefer the When\Should approach. The ‘When’ here represents the class name. The class will be responsible for setting up the ‘Context’ of the behavior (Think SetUp). The ‘Should’ represents the test methods of the class, the ‘Specification’.

    So taking your first class here AcmeEmployee_Should, we could change that represent some sort of event that occurs. I am thinking:

    When_An_Employee_Is_Created: (Context – create an employee)
    -Should_Have_A_Unique_Identity (Assert Specification)
    -Should_Have_A_First_Name (Assert Specification)
    -Email_Address_Should_Be_Valid (Assert Specification)
    Etc.

    So we have taken test focus away from the AcmeEmployee, and applied it to the behavior of when an employee is created. (And of course moved the code into a factory)

    Lets stab at one more, moving the focus away from the repository, to something that it “does”.

    When_Adding_A_New_Employee
    - Employee_Should_Not_Exist
    - Audit_Should_Indicate_Added_Date
    - Should_Record_Name_Of_User_Adding_Employee

    When_Attempting_To_Add_An_Existing_Employee
    - Should_Notify_User_Exists
    etc, etc

    Notice we do not talk about exceptions, id’s, singletons, construction etc. Just plain ol english a user might understand. We end up with a lot more test classes, but they are much more meaningful and easier comprehend. For a given context we may have 5 specifications or so, plus or minus 3. Ideally, we want all the work to happen in the setup (CreateContext, Before_Each_Specification) with the specification being one line of english as the test name, and one line of code doing the assertion.

    Most of this view comes from Scott Bellware’s style of BDD.(caught his session at Alt.Net Seattle) I think he has an app/runner that he is working on, though I just use NUnit.

  • http://elegantcode.com Jan Van Ryswyck

    I agree with Jarod. I’m also a fan of the When-Then approach. The framework from Scott Bellware he is referring to is called SpecUnit.NET and can be found on Google Code. (http://code.google.com/p/specunit-net/). You can take a look at the banking example for getting an idea of the naming style.

  • mike

    lately i’ve been encoding the Given/When on the test class name and every test starts with Should (i’m kinda leaning more to Given/When/Should).

    Given_AcmeEmployee_When_Create.Should_setup_Id
    Given_AcmeEmployee_When_Create.Should_setup_Name
    Given_AcmeEmployee_When_Create.Should_setup_LastName

    Given_AcmeEmployeeRepository_When_Delete_Employee.Should_not_have_Employee
    Given_AcmeEmployeeRepository_When_ClearAll_Employees.Should_not_have_any_Employee

    also notice that VS support for test lists is awful. i’d rather have a test list named ‘Given_Context’, then the test name ‘When_Action’ and every test name ‘Should_do something’. in that setup i would use 3 columns in the test result window. However, like i said, VS support for test list is pathetic :)

    cheers
    mike