单元测试 - 如何使用Jacoco计算代码覆盖率

4

我对计算代码行覆盖率感到有些困惑。

这是由Jacoco生成的报告快照 -

enter image description here

每个标签的含义是什么? - 指令分支复杂度方法

另外,MC代表什么?


这是哪个版本的Jacoco? - Jared Burrows
1个回答

5

M 表示缺失的行数/百分比与总数,而 C 表示覆盖的行数/百分比与总数。

PS:Jacoco Jenkins 仪表板仅显示缺失和覆盖的情况(总数),但不显示总数值/百分比。但是,如果您使用 Gradle 的 jacocoTestReport 任务生成的报告(即 index.html),则仅显示错过的数字/百分比,不显示已覆盖的数字/百分比(我猜在这种情况下,如果您知道错过了多少以及总数是多少,则其余部分#/% 就是已覆盖的)。好消息是,如果您匹配/计算这两个报告提供的缺失/覆盖/总数信息,即在 .html(index.html)中或在 Jenkins 工作的仪表板(Jacoco 插件也会读取 .exec 文件),它们是相同的!!(因为它们由相同的 .exec 文件生成)。

有关详细信息,请参见 Jacoco 覆盖率计数器。

您可以查看代码覆盖率尝试显示哪些覆盖率报告标头。

http://www.eecis.udel.edu/~zmanchun/vsl_osx64-1.1/src/jacoco/doc/counters.html

覆盖率计数器

JaCoCo 使用一组不同的计数器来计算覆盖度指标。所有这些计数器都源自包含 Java 字节码指令和调试信息(可选)的 Java 类文件中的信息。这种方法即使在没有源代码的情况下也可以对应用程序进行高效的即时检测和分析。在大多数情况下,收集到的信息可以映射回源代码并可视化到行级粒度。但是,这种方法存在局限性。类文件必须使用调试信息进行编译,以计算行级别覆盖范围并提供源突出显示。并非所有 Java 语言结构都可以直接编译为相应的字节码。在这种情况下,Java 编译器会创建所谓的合成代码,有时会导致意外的代码覆盖结果。

指令(C0 覆盖率)

JaCoCo 计算的最小单位是单个 Java 字节码指令。指令覆盖率提供有关已执行或未执行的代码量的信息。该指标完全独立于源格式,并且即使在类文件中没有调试信息的情况下也始终可用。

分支(C1 覆盖率)

JaCoCo 还为所有 if 和 switch 语句计算分支覆盖率。此度量标准计算方法中方法中此类分支的总数,并确定已执行或未执行的分支数。分支覆盖范围始终可用,即使类文件中没有调试信息也是如此。请注意,在此计数器定义的上下文中,异常处理不被视为分支。

如果使用调试信息编译了类文件,则可以将决策点映射到源行并相应地突出显示:

No coverage: No branches in the line has been executed (red diamond)
Partial coverage: Only a part of the branches in the line have been executed (yellow diamond)
Full coverage: All branches in the line have been executed (green diamond)

圈复杂度

JaCoCo还会为每个非抽象方法计算圈复杂度,并对类、包和组的复杂度进行总结。根据McCabe1996的定义,圈复杂度是能够以(线性)组合方式生成通过方法的所有可能路径的最小路径数。因此,复杂度值可作为覆盖某个软件特定部分所需单元测试用例数量的指标。即使在类文件中没有调试信息的情况下,也可以始终计算出复杂度数据。

圈复杂度v(G)的正式定义基于将方法的控制流图表示为一个有向图:

v(G) = E - N + 2 

E代表边的数量,N代表节点的数量。JaCoCo根据分支数(B)和决策点数(D)计算方法的圈复杂度,使用以下等价方程:

v(G) = B - D + 1 

根据每个分支的覆盖状态,JaCoCo还会为每个方法计算已覆盖和未覆盖的复杂性。未覆盖的复杂度再次表明模块完全覆盖所需的测试用例数量。请注意,由于JaCoCo不将异常处理视为分支,因此try/catch块也不会增加复杂性。 对于使用调试信息编译的所有类文件,可以计算每行代码的覆盖率信息。当至少执行了一个分配给此行的指令时,源代码行被认为是已执行的。
由于单个源代码行通常编译为多个字节码指令,因此源代码突出显示每行包含的三种不同状态:
- 已执行 - 未执行 - 部分执行
No coverage: No instruction in the line has been executed (red background)
Partial coverage: Only a part of the instruction in the line have been executed (yellow background)
Full coverage: All instructions in the line have been executed (green background)

方法

每个非抽象方法至少包含一条指令。只要执行了至少一条指令,就认为该方法已被执行。由于JaCoCo在字节码级别上工作,因此构造函数和静态初始化程序也被视为方法。其中一些方法可能在Java源代码中没有直接对应关系,例如隐式生成的默认构造函数或常量的初始化器。

当至少有一个方法被执行时,就认为类已经被执行。请注意,JaCoCo将构造函数以及静态初始化程序视为方法。由于Java接口类型可以包含静态初始化程序,因此这些接口也被视为可执行的类。 JaCoCo 0.6.3.20130409-1102 版权所有 © 2009、2013 Mountainminds GmbH & Co. KG 和贡献者


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接