Switch 的 eclemma 分支覆盖范围:19 个中的 7 个丢失 [英] eclemma branch coverage for switch: 7 of 19 missed

查看:43
本文介绍了Switch 的 eclemma 分支覆盖范围:19 个中的 7 个丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个开关系统,我正在使用 eclemma 来测试分支覆盖率.我们要求所有内容的分支覆盖率至少为 80%,因此我正在尝试尽可能多地进行测试.但是,eclemma 告诉我这个交换机系统没有在分支覆盖方面进行全面测试.

I have this switch system and I'm using eclemma to test the branch coverage. We are required to have at least 80% in branch coverage for everything so I'm trying to test as much as possible. However, eclemma tells me this switch system is not fully tested in terms of branch coverage.

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 个单独的案例 + 全部未定义).

I used straightforward JUnit tests to go trough each of these cases. Still eclemma marks this as yellow and says "7 of 19 branches missed". I would say there are only 7 ways to go through this switch system (the 6 individual cases+all undefined).

我尝试搜索有关堆栈溢出的类似问题.其中一些作为解决方案使用 if/else 进行全面覆盖.我不确定这是否是获得此报道的唯一途径.

I tried searching for similar questions on stack overflow. Some of them had as solutions to use if/else for full coverage. I'm not sure if this is the only way possible to get this coverage.

谁能解释一下这 19 个分支是从哪里来的,以及我如何测试剩下的 7 个分支以获得 100% 的分支覆盖率?

Can anybody explain where all these 19 branches come from and how I could test these remaining 7 to get a 100% branch coverage on this switch case?

推荐答案

Java 编译器将 switch-case 代码转换为 tableswitchlookupswitch.tableswitch 用于不同情况之间只有少数间隙的情况.否则,使用 lookupswitch.

The Java compiler translates the switch-case code either to a tableswitch or to a lookupswitch. The tableswitch is used when there are only a few gaps are between the different cases. Otherwise, the lookupswitch is used.

在您的情况下使用 tableswitch,因为您的情况的哈希码间隔很近(与 owaism 引用的代码不同):

In your case a tableswitch is used because the hash codes of your cases are closely spaced (unlike in the code referenced by 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 值.)

The numbers to the left of the colon are the ordered hash codes and the filled gaps between them, the numbers to the right are the jump destinations. (In Java, the hash code of a character is its ASCII value.)

68是D"(最低)的哈希码,83是S"(最高)的哈希码.69 是真实案例之间的差距之一的值,将跳转到默认案例.

68 is the hash code of "D" (the lowest one), and 83 is the hash code of "S" (the highest one). 69 is the value of one of the gaps between the real cases and will jump to the default case.

但是,我假设 EclEmma 从 tableswitch 的覆盖率计算中排除了这些分支(由于存在间隙,它会进一步降低覆盖率).所以我们有0(计数)个分支.

However, I assume that EclEmma excludes these branches from the coverage computation of a tableswitch (it would lower the coverage even more because of the gaps). So we have 0 (counted) branches yet.

接下来,在每个跳转目的地(默认情况之一除外)执行字符串值的等于比较.由于您的 switch-case 由 6 个 case 组成,我们有 6 个 6 跳转目标,并且具有相等的比较.

Next, an equals comparison of the string value is performed at each jump destination (except at the one of the default case). As your switch-case consists of 6 cases, we have 6 six jump destinations with an equals comparison.

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

The byte code of the comparison for case "G" is below:

  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 个分支用于比较.(默认情况下不分支.)

EclEmma counts two branches: either the input string and the case string are equals or they are not. Thus, we have 6 * 2 branches for the comparisons. (The default case does not branch.)

接下来,如果两个字符串相等,则将存储案例的索引(案例G"的字节代码行105-106).然后跳转到第二个 tableswitch 将被执行.否则直接执行跳转.

Next, if the two strings are equal the index of the case will be stored (byte code lines 105-106 for the case "G"). Then a jump to the second tableswitch will be executed. Otherwise, the jump will be executed directly.

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

这个开关对之前存储的case index进行操作,跳转到case中的code(caseG"有索引0,默认case有-1).EclEmma 计数 7 个分支(6 个案例加上默认案例).

This switch operates on the previously stored case index and jumps to the code in the case (case "G" has index 0, the default case has -1). EclEmma counts 7 branches (6 cases plus the default case).

因此,我们在第一个 tableswitch 中有 0 个计数分支,equals 比较中有 12 个分支,第二个 tableswitch 中有 7 个分支.总而言之,这导致 19 个分支.

Consequently, we have 0 counted branches in the first tableswitch, 12 branches in the equals comparisons and further 7 branches in the second tableswitch. All in all, this results in 19 branches.

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

Your tests do not cover any of the 6 not-equals branches. In order to cover these, you would need to find a string for each case which is not equal to the case condition but has the same hash code. It is possible, but definitively not sensible...

未来可能会调整 EclEmma 的分支计数.

Probably, the branch counting of EclEmma will be adjusted in the future.

此外,我猜您没有与任何案例不匹配的测试案例(因此不包括(隐式)默认案例.)

Moreover, I guess you don't have a test case which does not match with any of the cases (thus the (implicit) default case is not covered.)

这篇关于Switch 的 eclemma 分支覆盖范围:19 个中的 7 个丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆