I'm testing cobertura with my code and generated a simple report. Having a bit problem with understanding the numbers illustrated there.

There is only one class and the content is shown as in the image. The tests I wrote is as below,
public class AppTest {
@Before
public void before() {
}
@Test
public void addShouldReturnTheSumOfTwoIntegersWhenFirstIsLessThan100() {
Assert.assertTrue(65 == App.add(20, 45));
}
@Test
public void addShouldReturnMinusOneWhenFirstIsGreaterThan200() {
Assert.assertTrue(-1 == App.add(250, 45));
}
}
As shown in the image there are 4 branches. Can somebody explain how that number is 4 ?
UPDATE :
When I have only the below test case,
@Test
public void addShouldReturnMinusOneWhenFirstIsGreaterThan200() {
Assert.assertTrue(-1 == App.add(250, 45));
}
output ,

And when I have all 3 tests,
@Test
public void addShouldReturnTheSumOfTwoIntegersWhenFirstIsLessThan100() {
Assert.assertTrue(65 == App.add(20, 45));
}
@Test
public void addShouldReturnMinusOneWhenFirstIsGreaterThan200() {
Assert.assertTrue(-1 == App.add(250, 45));
}
@Test
public void addShouldReturn200WhenFirstIsGreaterThan100AndLessThan200() {
Assert.assertTrue(200 == App.add(120, 45));
}
output,

When I have the below test case for return 200 branch,
@Test
public void addShouldReturn200WhenFirstIsGreaterThan100AndLessThan200() {
Assert.assertTrue(200 == App.add(120, 45));
}
output,

UPDATE 2 :
If I have a test case to check the first if clause,
@Test
public void addShouldReturnTheSumOfTwoIntegersWhenFirstIsLessThan100() {
Assert.assertTrue(65 == App.add(20, 45));
}
output,

I think that hidden branch is not covered by only this test case. But any other below branch will cover the mysterious branch as well.
UPDATE 3:
After using javap -c App.class,
Compiled from "App.java"
public class com.vnb.play_cobertura.play_cobertura.App {
public com.vnb.play_cobertura.play_cobertura.App();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":
()V
4: return
public static int add(int, int);
Code:
0: iload_0
1: bipush 100
3: if_icmpge 10
6: iload_0
7: iload_1
8: iadd
9: ireturn
10: iload_0
11: sipush 200
14: if_icmpge 21
17: sipush 200
20: ireturn
21: iconst_m1
22: ireturn
}
De-compiled output,
package com.vnb.play_cobertura.play_cobertura;
public class App
{
public App() {}
public static int add(int a, int b)
{
if (a < 100)
return a + b;
if (a < 200) {
return 200;
}
return -1;
}
}
Based on the javap output there are branches at instructions 3 and 14. Each of those branches is evaluated independently by cobertura. Since each branch can have two different outcomes cobertura counts 4 paths in total for your method.
In general it's not feasible for cobertura or any other tool to find all dependencies between branches. So that's why those tools don't even try to do that.
The compiler transformed your code to something more like this (note the missing else before the second if):
if (a < 100) {
return a + b;
}
if (a < 200) {
return 200;
}
return -1;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With