Jader Dias
Jader Dias

Reputation: 90475

How to separate unit test methods?

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
}

Upvotes: 4

Views: 477

Answers (7)

Nat
Nat

Reputation: 9951

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.

Upvotes: 1

Talljoe
Talljoe

Reputation: 14827

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.

Upvotes: 1

Laurence Gonsalves
Laurence Gonsalves

Reputation: 143154

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.

Upvotes: 2

tvanfosson
tvanfosson

Reputation: 532455

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.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500485

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.

Upvotes: 7

Nader Shirazie
Nader Shirazie

Reputation: 10776

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.

Upvotes: 3

BengtBe
BengtBe

Reputation: 4495

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.

Upvotes: 4

Related Questions