Is branch coverage as useful as line coverage?
Asked Answered
D

2

8

My organization is emphasizing a line and branch coverage of 80%. I have absolutely no problem with the line coverage requirement, but the branch coverage has given me an issue.

Let's take the following case in point:

if(decisionA && decisionB)
{
  // path A - do some complex ninja code stuff
}
else
{
  // path B - tell user i can't do anything
}

Now, I've written 2 cases, the first one that covers path A and the second one covering path B. This should give me 100% line coverage. However, this gives me only 50% branch coverage since I've only covered (True && True) + (False && False) while ommitting (True && False) + (False && True).

From my perspective, the values of decisionA and decisionB are trivial, and hardly worth testing. However, the blanket requirement in my organization now means I would have to write 4 test cases instead of 2. Bring multiple if's and nested if's and this becomes complicated.

To me, it appears that it should be in the developer's decision whether he chooses to cover branch cases, so long as he deems that the important logic (in the case the ninja code stuff in part A) is getting covered.

What are your thoughts on this? What do you think would be an acceptable branch coverage rate? Is my angst about enforcing a high branch coverage rate justified or am I not emphasizing code quality enough? I know this is a bit of a subjective question, but surely there are good patterns already established regarding this.

Decennium answered 11/5, 2016 at 17:8 Comment(0)
B
8

First, terminology: what you're describing isn't branch coverage, that's "multiple condition coverage" or "compound condition coverage".

You definitely do not want to set a standard for multiple condition coverage; it's too much work for too little gain. For example, if your condition is a & b & c & d & e, where the five basic conditions are booleans, you have thirty-two tests to write, which is just not reasonable. It would be more reasonable to shoot for basic condition coverage: write one test with all five conditions false, then one test with each condition true, for a total of six.

Branch coverage means that tests exercise all paths through each branch, e.g. both the if and the else in your example. In your example line and branch coverage are both achieved by two tests; branch coverage is different if there is no else or there is more than one branch on a line. Branch coverage is a lot easier to achieve than multiple (or basic) condition coverage, some tools measure it, and it would be reasonable to set a standard for it instead of line coverage. Raedwald's point is good, although I address it by forbidding constructs that hide decisions in one-liners.

Brute answered 11/5, 2016 at 17:28 Comment(1)
Actually, an expression like a & b & ... would only need a large number of tests to be covered if the code uses logical non-short-circuit operators instead of conditional operators (&&) which are short-circuited. In practice, programmers use the short-circuit ones, requiring a much smaller number of tests. For example, given a test with a == false, we don't need another test with b == false to fully cover an expression containing a && b. The true reason why condition coverage can't be used is simply that existing code coverage tools do not support it.Gerta
F
8

Branch coverage is a more useful metric than line coverage, because code format changes can vary the value of the line coverage metric.

Consider these two code fragments, for the case that the condition is always true:

 If (condition) {
    good();
 } else {
    bad();
 }

and

 If (condition) {good();} else {bad();}

Both cases have a branch coverage of 50%. The second case has line coverage of 100%, the first case less.

Using line coverage as a metric can encourage developers to make useless changes to the format of their code, rather than improving quality by simplifying complex logic and improving quality assurance by adding more test cases.

Fairtrade answered 11/5, 2016 at 17:25 Comment(1)
I thought profilers would still treat that as multiple lines internally. Interesting.Decennium
B
8

First, terminology: what you're describing isn't branch coverage, that's "multiple condition coverage" or "compound condition coverage".

You definitely do not want to set a standard for multiple condition coverage; it's too much work for too little gain. For example, if your condition is a & b & c & d & e, where the five basic conditions are booleans, you have thirty-two tests to write, which is just not reasonable. It would be more reasonable to shoot for basic condition coverage: write one test with all five conditions false, then one test with each condition true, for a total of six.

Branch coverage means that tests exercise all paths through each branch, e.g. both the if and the else in your example. In your example line and branch coverage are both achieved by two tests; branch coverage is different if there is no else or there is more than one branch on a line. Branch coverage is a lot easier to achieve than multiple (or basic) condition coverage, some tools measure it, and it would be reasonable to set a standard for it instead of line coverage. Raedwald's point is good, although I address it by forbidding constructs that hide decisions in one-liners.

Brute answered 11/5, 2016 at 17:28 Comment(1)
Actually, an expression like a & b & ... would only need a large number of tests to be covered if the code uses logical non-short-circuit operators instead of conditional operators (&&) which are short-circuited. In practice, programmers use the short-circuit ones, requiring a much smaller number of tests. For example, given a test with a == false, we don't need another test with b == false to fully cover an expression containing a && b. The true reason why condition coverage can't be used is simply that existing code coverage tools do not support it.Gerta

© 2022 - 2024 — McMap. All rights reserved.