Search code examples
unit-testingassert

Is it bad practice to have more than one assertion in a unit test?


Is it bad practice to have more than one assertion in a unit test? Does it matter?


Solution

  • Sometimes I have exactly one assert per test case, but I think more often I have several assert statements.

    I've seen the case that @Arkain eludes to, where a very large piece of code has a single unit test suite with just a few test cases, and they are all labeled testCase1, testCase2, etc, and each test case has hundreds of asserts. And even better, each condition usually depends upon the side-effects of previous execution. Whenever the build fails, invariably in such a unit test, it takes quite some time to determine where the problem was.

    But the other extreme is what your question suggests: a separate test case for each possible condition. Depending on what you're testing, this might make sense, but often I have several asserts per test case.

    For instance, if you wrote java.lang.Integer, you might have some cases that look like:

    public void testValueOf() {
        assertEquals(1, Integer.valueOf("1").intValue());
        assertEquals(0, Integer.valueOf("0").intValue());
        assertEquals(-1, Integer.valueOf("-1").intValue());
        assertEquals(Integer.MAX_VALUE, Integer.valueOf("2147483647").intValue());
        assertEquals(Integer.MIN_VALUE, Integer.valueOf("-2147483648").intValue());
        ....
    }
    
    public void testValueOfRange() {
        assertNumberFormatException("2147483648");
        assertNumberFormatException("-2147483649");
        ...
    }
    
    public void testValueOfNotNumbers() {
        assertNumberFormatException("");
        assertNumberFormatException("notanumber");
        ...
    }
    
    private void assertNumberFormatException(String numstr) {
        try {
            int number = Integer.valueOf(numstr).intValue();
            fail("Expected NumberFormatException for string \"" + numstr +
                 "\" but instead got the number " + number);
        } catch(NumberFormatException e) {
            // expected exception
        }
    }
    

    Some simple rules that I can think of off hand for how many assert's to put in a test case:

    • Don't have more than one assert that depends on the side-effects of previous execution.
    • Group asserts together that test the same function/feature or facet thereof--no need for the overhead of multiple unit test cases when it's not necessary.
    • Any of the above rules should be overridden by practicality and common sense. You probably don't want a thousand unit test cases with a single assert in each (or even several asserts) and you don't want a single test case with hundreds of assert statements.