I am stuck in a situation where I am not able to fix the 1 of 6 branches issue. Below is the small code I tried to produce
package .example;
public class Testing {
public static final String ONE = "1";
public static boolean condition(String x, boolean y, String z) {
return "ABC".equalsIgnoreCase(x)
&& (y || ONE.equals(z));
}
}
Test case:
package .example;
import static .junit.jupiter.api.Assertions.assertFalse;
import static .junit.jupiter.api.Assertions.assertTrue;
import .junit.jupiter.api.Test;
class BranchCoverageTest {
@Test
public void testCondition_xIsABC_yTrue_zNotEqualOne() {
// Testing the case where the first branch is true, but the second branch is false
// "ABC".equalsIgnoreCase("ABC") is true, but (true || "1".equals("1")) is true
assertTrue(Testing.condition("ABC", true, "1"));
}
@Test
public void testCondition_xIsNotABC_yFalse_zEqualsOne() {
// Testing the case where the first branch is false, but the second branch is true
// "ABC".equalsIgnoreCase("DEF") is false, but (false || "1".equals("1")) is true
assertFalse(Testing.condition("DEF", false, "1"));
}
@Test
public void testCondition_xIsNotABC_yFalse_zNotEqualOne() {
// Testing the case where both branches are false
// "ABC".equalsIgnoreCase("DEF") is false, and (false || "1".equals("XYZ")) is false
assertFalse(Testing.condition("DEF", false, "XYZ"));
}
@Test
public void testCondition_xIsABC_yFalse_zNotEqualOne() {
// Testing the case where the first branch is true, but the second branch is false
// "ABC".equalsIgnoreCase("ABC") is true, and (false || "1".equals("XYZ")) is false
assertFalse(Testing.condition("ABC", false, "XYZ"));
}
}
I am stuck in a situation where I am not able to fix the 1 of 6 branches issue. Below is the small code I tried to produce
package .example;
public class Testing {
public static final String ONE = "1";
public static boolean condition(String x, boolean y, String z) {
return "ABC".equalsIgnoreCase(x)
&& (y || ONE.equals(z));
}
}
Test case:
package .example;
import static .junit.jupiter.api.Assertions.assertFalse;
import static .junit.jupiter.api.Assertions.assertTrue;
import .junit.jupiter.api.Test;
class BranchCoverageTest {
@Test
public void testCondition_xIsABC_yTrue_zNotEqualOne() {
// Testing the case where the first branch is true, but the second branch is false
// "ABC".equalsIgnoreCase("ABC") is true, but (true || "1".equals("1")) is true
assertTrue(Testing.condition("ABC", true, "1"));
}
@Test
public void testCondition_xIsNotABC_yFalse_zEqualsOne() {
// Testing the case where the first branch is false, but the second branch is true
// "ABC".equalsIgnoreCase("DEF") is false, but (false || "1".equals("1")) is true
assertFalse(Testing.condition("DEF", false, "1"));
}
@Test
public void testCondition_xIsNotABC_yFalse_zNotEqualOne() {
// Testing the case where both branches are false
// "ABC".equalsIgnoreCase("DEF") is false, and (false || "1".equals("XYZ")) is false
assertFalse(Testing.condition("DEF", false, "XYZ"));
}
@Test
public void testCondition_xIsABC_yFalse_zNotEqualOne() {
// Testing the case where the first branch is true, but the second branch is false
// "ABC".equalsIgnoreCase("ABC") is true, and (false || "1".equals("XYZ")) is false
assertFalse(Testing.condition("ABC", false, "XYZ"));
}
}
Share
Improve this question
edited Mar 5 at 10:38
avandeursen
8,6783 gold badges43 silver badges54 bronze badges
asked Mar 3 at 17:36
PAAPAA
12.1k58 gold badges197 silver badges314 bronze badges
5
|
2 Answers
Reset to default 1I was able to fix it by using below test cases
package .example;
import static .junit.jupiter.api.Assertions.assertFalse;
import static .junit.jupiter.api.Assertions.assertTrue;
import .junit.jupiter.api.Test;
class BranchCoverageTest {
@Test
public void testCondition_XEqualsABC_YTrue() {
// x = "ABC", y = true, z = "any"
// true, true, false
assertTrue(Testing.condition("ABC", true, "any"));
}
// Done
@Test
public void testCondition_XEqualsABC_YFalse_ZEqualsOne() {
// x = "ABC", y = false, z = "1"
// true, false, true
assertTrue(Testing.condition("ABC", false, "1"));
}
// Done
@Test
public void testCondition_XEqualsABC_YFalse_ZNotOne() {
// x = "ABC", y = false, z = "not 1"
// true, false, false
assertFalse(Testing.condition("ABC", false, "not 1"));
}
@Test
public void testCondition_XNotEqualsABC() {
// x = "DEF", y = true, z = "any"
// false, true, false
assertFalse(Testing.condition("DEF", true, "any"));
}
}
Interesting case. There are various adequacy criteria you could target.
For clarity: there are 3 conditions here (x = ABC, y = true, and z = 1), and the overall predicate (which can yield true or false).
Possible targets:
Just the predicate: All you want is that the predicate yields true and yields false. This can be achieved by just two test cases (e.g., one with x = ABC and one in which x!= ABC, and for both y=true and z=1)
Every condition true or false: All you want is that each individual condition is true as well as false in at least one test case. This can be achieved with just two test cases (x=ABC, y=false, z=2, and x=AAA, y=true, z=1). Note in this case the predicate outcome is "false" in both cases.
MC/DC or Modified Condition/Decision Coverage, in which you ensure that each condition individually flips the predicate outcome. With three conditions you'd have four test cases -- for example:
- T1: x = ABC, y = false, z = 1, predicate result true
- T2: x != ABC, y = false, z = 1, predicate result false (first condition flips w.r.t. T1)
- T3: x = ABC, y = true, z = 1, predicate result false (2nd condition flips w.r.t. T1)
- T4: x != ABC, y = false, z = 2, predicate result false (3rd condition flips w.r.t. T1)
Full condition coverage: where you insist on trying all 2^3 = 8 combinations -- the most exhaustive, and the most expensive.
Note that the final test suite provided in the answer is (very similar to) the MC/DC cover.
The 'branches' as mentioned by JaCoCo correspond in this case to individual conditions. You can think of them in branches of a tree for the short-circuit evaluation of the expression.
2*2*2
) combinations to be tested... I see 4 - considering the first element being"ABC"
, we got 4 cases to test; only 2 are being tested || ¹ not counting upper/lower-case alternatives (first parameter) – user85421 Commented Mar 3 at 17:51&&
and||
can short-cut. – Sören Commented Mar 3 at 19:33add(1, 2) == 3
it could be implemented asint add(int x, int y) { return 1 + 2; }
(intentional absurd example - and I am well aware that often it is not possible/feasible to test all combinations) – user85421 Commented Mar 3 at 20:39