1

Suppose we're unit testing a class with xUnit-like framework - so a test class is created for class-under-test. Now, how much should be tested by individual test methods?

Should there be one-to-one mapping between methods-under-test and test methods:

class TestMath {

    testSqrt() {
        assertEquals(Math.sqrt(4), 2);

        assertException(Math.sqrt(-2));
    }
}

Or is it better to have one test method per "scenario":

class TestMath {

    testSqrtOfPositiveNum() {
        assertEquals(Math.sqrt(4), 2);
    }

    testSqrtOfNegativeNum() {
        assertException(Math.sqrt(-2));
    }
}

Which is better and what are pros and cons of both methods?

3 Answers 3

5

The second approach is better. If one of the tests fail, you will instantly know what the problem is. If your test methods check many conditions, if one of them fails, you will have to dig through it to figure out what the problem is.

4

Personally I prefer the scenario approach, it more closely resembles how the code will be used and is less likely to break just do to some change in the way the underlying code works.

3
  • 2
    Also, keep in mind that putting multiple, dissimilar tests in one method (first approach) will not fully exercise your classes - as soon as one of them fails, the rest of the assertions in that test method do not even run. Commented Mar 20, 2013 at 20:51
  • It depends on test framework. Most behave this way, though. Commented Mar 20, 2013 at 20:55
  • @el.pescado no with you first example if the test failed the -2 case is never executed, it will in your second example Commented Mar 20, 2013 at 22:14
2

The general rule is have one assert per test.

As far as the level to which you should test. I like to extract core logic into logic engines that can be tested using low level method level unit tests. But also have higher level tests that run at a scenario level. This way the high level tests speak the functionality of the whole system and the low level tests make sure that all the paths are tested correctly. When something breaks you can see where it is that it has broken but also how the break will manifest at a higher level.

In your case I would definitely split it out into two tests so that you can see exactly what has broken rather than just knowing that something has broken.

Not the answer you're looking for? Browse other questions tagged or ask your own question.