views:

124

answers:

5

I have difficulty in many situations to come up with a good unit test names for classes and methods. Typically, I try to follow the form:

public class TestContext
{
    [Fact]
    public void WhenThis_DoThat()
    {
    }
}

Some put words Given, When, and Then on the parts to be explicit. I like it because it seems to make the unit test clearer on what it is that it's testing. Aside from considering BDD toolkits, I need some advice in how this can work with plain old xUnit tools.

I'm having especially hard time with scenarios like this:

When Application starts up, the main form loads and user sees a list of links which the user can click on.

or maybe a better use case scenario is:

User can select a link from a list of links.

I'm not certain but I'm trying to describe a behavior where you run an app and the form loads with a list of clickable links. And turning that into a unit test.

What is the Given, When, and Then for that?

A: 

I try to follow Roy Osherove's approach:

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

blu
So, to give an example, what would you name the tests which were given as examples in the OP?
ChrisW
I like Roy's style as well - I bought his Art of Unit Testing book by the way which is very good - but like ChrisW, could you try my example using Roy's approach?
Jiho Han
A: 

In your scenario what can go wrong? A unit test needs to test something, so what are you testing.

FormHasLinks?

LoadForm? //then check for links

Maybe if you say what your testing rather than what your doing you might find it easier.

Toby Allen
The thing I am testing in my example is whether the list of links show up on the form when the app starts.
Jiho Han
A: 

I name my tests after the input, not after the output. I describe the scenario which is being tested: I don't try to define, in the name of the test case, what the required output is in that scenario.

For example, the following test the behaviour of the Backspace key in a text editor, in various scenarios:

  • Backspace after space
  • Backspace around edges of inline textrun
  • Backspace at beginning of paragraph
  • Backspace near end of line
  • Backspace normalize within paragraph
  • Backspace selected word and both spaces
  • Backspace selected word and space
  • Backspace selected word
  • Backspace selection spans two paragraphs
  • Backspace several words
  • Backspace space and selected word
  • Backspace to far edge of other block

Thus you can see more-or-less what scenarios are being tested (but it doesn't also try to tell you what the expected behaviour is in each scenario).

ChrisW
+4  A: 

Here is how I write tests in BDD specification style: http://github.com/orfjackal/tdd-tetris-tutorial

What is needed, is the ability to have multiple test fixtures in one class. Then it's possible to organize the tests so, that each fixture is the "Given/When" part and each test method is the "Then" part. JUnit does not support it, so I wrote a simple test runner for it:

@RunWith(NestedJUnit4.class)
public class WerewolfTest extends Assert {
    public class Given_the_moon_is_full {
        @Before public void When_you_walk_in_the_woods() {
            ...
        }
        @Test public void Then_you_can_hear_werewolves_howling() {
            ...
        }
        @Test public void Then_you_wish_you_had_a_silver_bullet() {
            ...
        }
    }
    public class Given_the_moon_is_not_full {
        @Before public void When_you_walk_in_the_woods() {
            ...
        }
        @Test public void Then_you_do_not_hear_any_werewolves() {
            ...
        }
        @Test public void Then_you_are_not_afraid() {
            ...
        }
    }
}
Esko Luontola
+2  A: 

I'm quoting Introducing BDD from Dan North:

Test method names should be sentences

My first "Aha!" moment occurred as I was being shown a deceptively simple utility called agiledox, written by my colleague, Chris Stevenson. It takes a JUnit test class and prints out the method names as plain sentences, so a test case that looks like this:

public class CustomerLookupTest extends TestCase { testFindsCustomerById() { ... } testFailsForDuplicateCustomers() { ... } ... }

renders something like this:

CustomerLookup – finds customer by id – fails for duplicate customers – ...

The word "test" is stripped from both the class name and the method names, and the camel-case method name is converted into regular text. That’s all it does, but its effect is amazing.

Developers discovered it could do at least some of their documentation for them, so they started to write test methods that were real sentences. What’s more, they found that when they wrote the method name in the language of the business domain,the generated documents made sense to business users, analysts, and testers.

The whole paper is actually worth the read. Warmly recommended!

Pascal Thivent