Unit Testing – Testing Multiple Conditions in an IF Statement

unit testing

I have a chunk of code that looks something like this:

function bool PassesBusinessRules()
{
    bool meetsBusinessRules = false;

    if (PassesBusinessRule1 
         && PassesBusinessRule2
         && PassesBusinessRule3)
    {
         meetsBusinessRules= true;
    }

    return meetsBusinessRules;
}

I believe there should be four unit tests for this particular function. Three to test each of the conditions in the if statement and ensure it returns false. And another test that makes sure the function returns true.

Question: Should there actually be ten unit tests instead? Nine that checks each of the possible failure paths. IE:

  • False False False
  • False False True
  • False True False

And so on for each possible combination.

I think that is overkill, but some of the other members on my team do not. The way I look at it is if BusinessRule1 fails then it should always return false, it doesn't matter if it was checked first or last.

Best Answer

Formally, those types of coverage have names.

First, there's predicate coverage: you want to have a test case that makes the if statement true, and one that makes it false. Having this coverage met is probably a basic requirement for a good test suite.

Then there Condition Coverage: Here you want to test that each sub-condition in the if has the value true and false. This obviously creates more tests, but it usually catches more bugs, so it's often a good idea to include in your test suite if you have time.

The most advanced coverage criteria is usually called Combinatorial Condition Coverage: Here the goal is to have a test case that goes through all possible combinations of boolean values in your test.

Is this better than simple predicate or condition coverage? In terms of coverage, of course. But it's not free. It comes at a a very high cost in test maintenance. For this reason, most people don't bother with full combinatorial coverage. Usually testing all branches (or all conditions), will be good enough for catching bugs. Adding the extra tests for combinatorial testing won't usually catch more bugs, but requires a lot of effort to create and maintain. The extra effort usually makes this not worth the very very small payoff, so I wouldn't recommend this.

Part of this decision should be based on how risky you think that code will be. If it has a lot of room to fail, it's worth testing. If it's somewhat stable, and won't change much, you should consider focusing your testing efforts elsewhere.

Related Topic