最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - 1 of 6 branches missing issue using Jacoco - Stack Overflow

programmeradmin0浏览0评论

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 there are 3 conditions, so there (at least¹) are 8 (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
  • @user85421 when you say at least, do you mean at most? && and || can short-cut. – Sören Commented Mar 3 at 19:33
  • The comments in you first test method are very misleading. – Sören Commented Mar 3 at 19:39
  • @Sören no, I indeed mean "at least", as I wrote 3 conditions and additionally ignored case. I usually do not write my tests (solely) based on the code¹ being tested, but on specification/functionality (and even if done based on code, code is ignoring case, we at least got an additional condition, if we can call that so). And, even considering short-cut, as we can see in the question, it is not testing all cases: quoting myself "considering the first element being "ABC", we got 4 cases to test; only 2 are being tested" || ¹ ... – user85421 Commented Mar 3 at 20:31
  • ... to test a simple add method I would never be happy having only one single test like add(1, 2) == 3 it could be implemented as int 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
Add a comment  | 

2 Answers 2

Reset to default 1

I 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.

发布评论

评论列表(0)

  1. 暂无评论