tags:

views:

110

answers:

7

Imagine I have a method:

void Method(bool parameter){
    if(parameter){
        // first case
    } else {
        // second case
    }
}

Which is your preferred unit test organization method?

Option 1:

void MethodTest(){
  // test first case
  // test second case
}

or

Option 2:

void MethodTestFirstCase(){
  // test first case
}

void MethodTestSecondCase(){
  // test second case
}
+4  A: 

Option 2.

You should test only one thing in each test. It will also be difficult to give the test a good name if it test more than one thing.

When a test fails it should also be easy to locate the error, without using the debugger. If the test covers more than one thing then the error can be multiple places.

BengtBe
+3  A: 

Option 2 is usually preferable.

The advantage there is you get visibility in the Unit test runner for each test separately, rather than having to see where a failure occurred if something goes wrong.

Also, as you develop, its easier to run more focused tests to get feedback faster.

Nader Shirazie
+6  A: 

In this case I'd test the two separately.

Having said that, I'm not dogmatic about the "test only one thing per test" approach. Sometimes it just makes more pragmatic sense to test multiple things in the same test - in particular if getting to one end point means going through another point, it's sometimes okay to combine the two.

In this case you really would be testing two separate things rather than one on the way to another, so I'd split them up.

Jon Skeet
+1 for "one on the way to another". that's usually good justification for multiple checks within a single test.
Nader Shirazie
A: 

I would have a class (suite) of tests that test all of the different methods in the class under test. This class (suite) would have a different test method for each variant of a particular feature. This doesn't mean that you have to have one test per line of code in the method. You can decide the granularity of a "feature" with respect to a single method, but they are usually small. In your case I'd say that you have two "features", one when the parameter passes the test, another when it fails. Thus, I would have, at least, two tests for this method. Typically, you will have only one, or perhaps a few, assertions per test case.

tvanfosson
+2  A: 

With option 1, if the first case fails the second case won't be tested at all. With option 2 (in most unit testing frameworks), if the first case fails the second case will still be tested.

This makes option 2 superior, because you can distinguish between the situation where only the first case is broken and where both cases are broken, which makes it much easier to debug when things go wrong.

Laurence Gonsalves
+1  A: 

I tend to use Option 3:

[TestClass]
public class When_parameter_is_a {
    setup() {} // arrange
    execute() {} // act
    [TestMethod]
    this_should_happen() {} // assert
    [TestMethod]
    this_should_happen_too() {} //assert
}

[TestClass]
public class When_parameter_is_b {
    setup() {}
    execute() {}
    [TestMethod]
    this_should_happen() {}
    [TestMethod]
    this_should_happen_too() {}
}

Then test all of the expected behavior for each part. This is a BDD-style (Behavior Driven Design) test and puts emphasis on the behavior in certain contexts, rather than testing the "implementation" of the method.

Talljoe
+1 for BDD -AND- MSTest
Jeremy Frey
+1  A: 

Neither.

Don't think about testing the methods of the class, instead think about testing things that the class does -- the services that it provides to other objects. When you do this, you'll find that you don't have test methods that are named after the methods of the class under test. And you don't have the problem of finding names for tests when more than one test exercises the same method(s) of the class under test.

Nat