当前位置: 首页 > 知识库问答 >
问题:

开关的eclemma分支覆盖: 19个中的7个错过了

郭阳曜
2023-03-14

我有一个交换系统,我用eclemma测试分支覆盖率。我们需要有至少80%的分支覆盖率,所以我正在尝试尽可能多的测试。然而,eclemma告诉我,这个交换机系统在分支覆盖方面没有经过充分测试。

pos = p.getCurrentPosition().substring(0, 1);
switch (pos) {
            case "G":
                goalkeepers++;
                break;
            case "D":
                defense++;
                break;
            case "M":
                midfield++;
                break;
            case "F":
                offense++;
                break;
            case "S":
                substitutes++;
                break;
            case "R":
                reserves++;
                break;
        }

我使用了简单的JUnit测试来测试每一个案例。仍然eclemma将其标记为黄色,并表示“19个分支中有7个错过了”。我会说只有7种方法可以通过这个交换系统(6个单独的案例都没有定义)。

我试着在堆栈溢出上搜索类似的问题。他们中的一些人将其作为解决方案,使用if/else进行全面覆盖。我不确定这是不是唯一能得到保险的方法。

有谁能解释一下这19个分支来自何处,以及我如何测试剩下的7个分支,从而在这个交换机外壳上获得100%的分支覆盖率?

共有2个答案

梁华皓
2023-03-14

查看以下链接:http://sourceforge.net/p/eclemma/discussion/614869/thread/80e770df/

以下是上面链接的片段:

这是一个带有3个外壳的开关示例

这是一个非常有趣的观察。从字节码可以看出Java编译器是如何处理字符串开关的。实际上这是一个三步过程:

  1. 打开哈希代码(3个分支,1个默认值)
  2. 对于每个哈希代码做一个等于(3*2分支)
  3. 为实际执行案例做最后的切换(3个分支,1个默认)

因此,我们总共有14个分支,从源代码的角度来看,它们看起来很奇怪。更奇怪的是,你少了三个。解释是第2步,在散列码之后附加应用equals方法。要覆盖这些分支,还需要找到具有相同哈希代码的其他字符串。这肯定是从未来版本的JaCoCo的报道中过滤出来的:
https://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions

章涵容
2023-03-14

Java编译器将开关大小写代码转换为表开关查找开关。当不同情况之间只有少量间隙时,使用表开关。否则,将使用查找开关

在您的案例中,使用表开关,因为案例的哈希代码间隔很近(与owaism引用的代码不同):

  16: tableswitch   { // 68 to 83
                68: 111 // 'D'
                69: 183
                70: 141 // 'F'
                71: 96  // 'G'
                72: 183
                73: 183
                74: 183
                75: 183
                76: 183
                77: 126 // 'M'
                78: 183
                79: 183
                80: 183
                81: 183
                82: 171 // 'R'
                83: 156 // 'S'
           default: 183
      }

冒号左边的数字是有序散列码和它们之间的填充间隙,右边的数字是跳转目的地。(在Java中,字符的哈希代码是其ASCII值。)

68是"D"的哈希码(最低的一个),83是"S"的哈希码(最高的一个)。69是真实情况之间的差距之一的值,并将跳转到默认情况。

但是,我假设EclEmma将这些分支排除在表开关的覆盖率计算之外(由于存在间隙,这将进一步降低覆盖率)。所以我们已经有0个分支了。

接下来,在每个跳转目的地执行字符串值的相等比较(默认情况除外)。由于您的开关案例由6个案例组成,我们有6个具有相等比较的跳转目的地。

案例“G”的比较字节码如下:

  96: aload_3
  97: ldc           #10
  99: invokevirtual #11  java/lang/Object;)Z
 102: ifeq          183
 105: iconst_0
 106: istore        4
 108: goto          183
 111: aload_3

EclEmma统计两个分支:输入字符串和大小写字符串是否相等。因此,我们有6*2个分支用于比较。(默认情况下不会分支。)

接下来,如果两个字符串相等,将存储大小写的索引(大小写“G”的字节码行105-106)。然后跳转到第二个表开关。否则,将直接执行跳转。

 185: tableswitch   { // 0 to 5
                 0: 224
                 1: 237
                 2: 250
                 3: 263
                 4: 276
                 5: 289
           default: 299
      }

此开关在先前存储的案例索引上操作,并跳转到案例中的代码(案例“G”具有索引0,默认案例具有-1)。EclEmma统计了7个分支(6个案例加上默认案例)。

因此,我们在第一个表开关中有0个计数的分支,在等于比较中有12个分支,在第二个表开关中还有7个分支。总而言之,这导致了19个分支。

您的测试不包括6个不相等分支中的任何一个。为了覆盖这些分支,您需要为每个大小写找到一个不等于大小写条件但具有相同哈希代码的字符串。这是可能的,但绝对不明智...

可能,EclEmma的分支计数将在未来进行调整。

此外,我猜您没有与任何情况不匹配的测试用例(因此(隐式)默认情况没有涵盖。)

 类似资料:
  • 问题内容: 我有此交换系统,并且正在使用eclemma测试分支覆盖范围。我们要求所有分支机构的分支覆盖率至少为80%,因此我正在尝试进行尽可能多的测试。但是,问题告诉我,此交换系统尚未在分支机构覆盖范围内进行全面测试。 我使用了简单的JUnit测试来处理上述每种情况。仍然有两极分化将此标记为黄色,并说“ 19个分支中有7个未命中”。我要说的是,只有7种方法可以通过此交换系统(6种情况+所有未定义)

  • 问题内容: 我们正在将EasyMock和PowerMock与JUnit一起使用。使用的覆盖率工具是ECLEmma。使用EasyMock,它会以绿色正确显示覆盖范围(已覆盖)。但是,对于使用PowerMock进行了单元测试的代码,覆盖范围显示为红色(未覆盖)。在网络上阅读过类似的问题。但是,只想检查是否有解决方案。 谢谢 Venkatesh 问题答案: 这是一个已知的问题:https : //git

  • 我是jUnit的新手,我试图加深我对它的了解。我在网上搜索了一下,但没有找到任何可以解决几个疑问的东西。 这是代码: 这是jUnit4测试用例: TestCase运行正常,没有任何问题,但我有两个简单的问题/问题: 1) 只测试方法的正确功能是正确的,还是应该同时测试值和/或任何特定异常? 2) 当我用EclEmma运行代码覆盖率时,它给了我75%的代码覆盖率,因为测试用例没有测试类的构造函数。测

  • 我使用lcov2.0来检测分支覆盖率,但是会遇到很多和std容器相关的分支未覆盖的问题。 g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 gtest 1.12.x lcov/genhtml: LCOV version 2.0-1 源码 gtest代码 lcov最终生成的报告长这样,所有insert和emplace相关的函数都会有一个未解决的分支 贴出我用的lco

  • 主要内容:如何计算分支覆盖范围?分支覆盖技术用于覆盖控制流图的所有分支。它至少涵盖决策点的每个条件的所有可能结果(真和假)。分支覆盖技术是一种白盒测试技术,可确保每个决策点的每个分支都必须执行。 然而,分支覆盖技术和决策覆盖技术非常相似,但两者之间存在关键差异。决策覆盖技术涵盖每个决策点的所有分支,而分支测试涵盖代码的每个决策点的所有分支。 换句话说,分支覆盖遵循决策点和分支覆盖边缘。许多不同的指标可用于查找分支覆盖范围和决策覆

  • 我刚刚在eclipse中安装了Eclemma,并创建了一个JUnit测试。我运行了测试,它成功了,绿色和红色的横幅显示在我的程序中,但我看不到任何“覆盖率”视图,如所示的指令(也不在窗口显示视图中)。 我如何解决这个问题?我必须重写我的JUnit测试还是重新安装EclEmma? 谢谢