单元测试 - 如何使用 Jacoco 计算线路覆盖率
Unit testing - How to calculate the line coverage using Jacoco
我对计算线路覆盖率有点困惑。
这是 Jacoco 生成的报告的快照 -
每个标签的含义是什么? - Instruction
, branch
, complexity
, line
, method
, class
.
另外 M
和 C
代表什么?
M 表示缺少总数中的 lines/percentage 并且 C 表示覆盖总数中的 lines/percentage .
PS:Jacoco Jenkins 仪表板仅显示缺失和覆盖(超出总计)但 不显示总计 number/value /%。但是如果你正在使用 Gradle 的 jacocoTestReport 任务生成的报告(即 index.html),那么它只显示 missed #s/percentage 和 不显示 Covered#s/%(我想,在这种情况下,如果您知道遗漏了多少和总共有多少,那么 rest#/% 就会被覆盖)。
好消息是,如果您 match/calculate 这两个报告为 missing/covered/total 提供的信息,即在 .html (index.html) 中或您在 Jenkins 作业的仪表板中看到的信息 (Jacoco也读取 .exec 文件的插件),它们匹配!! (因为它们是由相同的 .exec 文件生成的)。
有关更多详细信息,请参阅 Jacoco 覆盖计数器。
您可以查看代码覆盖率,它试图显示什么样的覆盖率报告headers。
http://www.eecis.udel.edu/~zmanchun/vsl_osx64-1.1/src/jacoco/doc/counters.html
覆盖计数器
JaCoCo 使用一组不同的计数器来计算覆盖率指标。所有这些计数器都来自 Java class 文件中包含的信息,这些文件基本上是 Java 字节代码指令和可选地嵌入在 class 文件中的调试信息。这种方法允许高效 on-the-fly 对应用程序进行检测和分析,即使在没有源代码可用的情况下也是如此。在大多数情况下,收集的信息可以映射回源代码,并可视化到行级粒度。无论如何,这种方法有局限性。 class 文件必须使用调试信息进行编译,以计算行级覆盖率并提供源代码突出显示。并非所有 Java 语言结构都可以直接编译为相应的字节码。在这种情况下,Java 编译器会创建所谓的合成代码,有时会导致意外的代码覆盖结果。
说明(C0覆盖率)
JaCoCo 计数的最小单位是单个 Java 字节代码指令。指令覆盖率提供有关已执行或未执行的代码量的信息。此指标完全独立于源格式并且始终可用,即使 class 文件中没有调试信息也是如此。
分支机构(C1 覆盖范围)
JaCoCo 还计算所有 if 和 switch 语句的分支覆盖率。该指标计算方法中此类分支的总数,并确定已执行或错过的分支数。分支覆盖始终可用,即使 class 文件中没有调试信息。请注意,在此计数器定义的上下文中,异常处理不被视为分支。
如果 class 文件没有使用调试信息编译,决策点可以映射到源代码行并相应地突出显示:
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 还计算每个 non-abstract 方法的圈复杂度,并总结 classes、包和组的复杂度。根据 McCabe1996 的定义,圈复杂度是可以(线性)组合通过一种方法生成所有可能路径的最小路径数。因此,复杂性值可以作为完全覆盖某个软件的单元测试用例数量的指示。即使 class 文件中没有调试信息,也始终可以计算复杂度数字。
圈复杂度 v(G) 的正式定义基于方法的控制流图表示为有向图:
v(G) = E - N + 2
其中 E 是边数,N 是节点数。 JaCoCo根据分支数(B)和决策点数(D)用以下等价方程计算方法的圈复杂度:
v(G) = B - D + 1
基于每个分支的覆盖状态,JaCoCo 还计算了每个方法的覆盖和遗漏复杂度。遗漏的复杂性再次表明完全覆盖模块所遗漏的测试用例数量。请注意,由于 JaCoCo 不考虑异常处理,因为分支 try/catch 块也不会增加复杂性。
行数
对于所有class个编译后带有调试信息的文件,可以计算出各个行的覆盖率信息。当分配给该行的至少一条指令已被执行时,源代码行被视为已执行。
由于单行通常会编译为多字节代码指令,因此源代码突出显示会为包含源代码的每一行显示三种不同的状态:
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)
方法
每个non-abstract方法至少包含一条指令。当至少一条指令已被执行时,一个方法被认为已执行。作为 JaCoCo 工作 o字节码级别的构造函数和静态初始值设定项也算作方法。其中一些方法在 Java 源代码中可能没有直接对应关系,例如隐式生成的默认构造函数或常量初始化程序。
类
A class 当至少有一个方法被执行时被认为是已执行。请注意,JaCoCo 将构造函数和静态初始值设定项视为方法。由于 Java 接口类型可能包含静态初始值设定项,因此此类接口也被视为可执行 classes。
JaCoCo 0.6.3.20130409-1102 版权所有 © 2009、2013 Mountainminds GmbH & Co. KG 和贡献者
我对计算线路覆盖率有点困惑。
这是 Jacoco 生成的报告的快照 -
每个标签的含义是什么? - Instruction
, branch
, complexity
, line
, method
, class
.
另外 M
和 C
代表什么?
M 表示缺少总数中的 lines/percentage 并且 C 表示覆盖总数中的 lines/percentage .
PS:Jacoco Jenkins 仪表板仅显示缺失和覆盖(超出总计)但 不显示总计 number/value /%。但是如果你正在使用 Gradle 的 jacocoTestReport 任务生成的报告(即 index.html),那么它只显示 missed #s/percentage 和 不显示 Covered#s/%(我想,在这种情况下,如果您知道遗漏了多少和总共有多少,那么 rest#/% 就会被覆盖)。 好消息是,如果您 match/calculate 这两个报告为 missing/covered/total 提供的信息,即在 .html (index.html) 中或您在 Jenkins 作业的仪表板中看到的信息 (Jacoco也读取 .exec 文件的插件),它们匹配!! (因为它们是由相同的 .exec 文件生成的)。
有关更多详细信息,请参阅 Jacoco 覆盖计数器。
您可以查看代码覆盖率,它试图显示什么样的覆盖率报告headers。
http://www.eecis.udel.edu/~zmanchun/vsl_osx64-1.1/src/jacoco/doc/counters.html
覆盖计数器
JaCoCo 使用一组不同的计数器来计算覆盖率指标。所有这些计数器都来自 Java class 文件中包含的信息,这些文件基本上是 Java 字节代码指令和可选地嵌入在 class 文件中的调试信息。这种方法允许高效 on-the-fly 对应用程序进行检测和分析,即使在没有源代码可用的情况下也是如此。在大多数情况下,收集的信息可以映射回源代码,并可视化到行级粒度。无论如何,这种方法有局限性。 class 文件必须使用调试信息进行编译,以计算行级覆盖率并提供源代码突出显示。并非所有 Java 语言结构都可以直接编译为相应的字节码。在这种情况下,Java 编译器会创建所谓的合成代码,有时会导致意外的代码覆盖结果。
说明(C0覆盖率)
JaCoCo 计数的最小单位是单个 Java 字节代码指令。指令覆盖率提供有关已执行或未执行的代码量的信息。此指标完全独立于源格式并且始终可用,即使 class 文件中没有调试信息也是如此。
分支机构(C1 覆盖范围)
JaCoCo 还计算所有 if 和 switch 语句的分支覆盖率。该指标计算方法中此类分支的总数,并确定已执行或错过的分支数。分支覆盖始终可用,即使 class 文件中没有调试信息。请注意,在此计数器定义的上下文中,异常处理不被视为分支。
如果 class 文件没有使用调试信息编译,决策点可以映射到源代码行并相应地突出显示:
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 还计算每个 non-abstract 方法的圈复杂度,并总结 classes、包和组的复杂度。根据 McCabe1996 的定义,圈复杂度是可以(线性)组合通过一种方法生成所有可能路径的最小路径数。因此,复杂性值可以作为完全覆盖某个软件的单元测试用例数量的指示。即使 class 文件中没有调试信息,也始终可以计算复杂度数字。
圈复杂度 v(G) 的正式定义基于方法的控制流图表示为有向图:
v(G) = E - N + 2
其中 E 是边数,N 是节点数。 JaCoCo根据分支数(B)和决策点数(D)用以下等价方程计算方法的圈复杂度:
v(G) = B - D + 1
基于每个分支的覆盖状态,JaCoCo 还计算了每个方法的覆盖和遗漏复杂度。遗漏的复杂性再次表明完全覆盖模块所遗漏的测试用例数量。请注意,由于 JaCoCo 不考虑异常处理,因为分支 try/catch 块也不会增加复杂性。 行数
对于所有class个编译后带有调试信息的文件,可以计算出各个行的覆盖率信息。当分配给该行的至少一条指令已被执行时,源代码行被视为已执行。
由于单行通常会编译为多字节代码指令,因此源代码突出显示会为包含源代码的每一行显示三种不同的状态:
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)
方法
每个non-abstract方法至少包含一条指令。当至少一条指令已被执行时,一个方法被认为已执行。作为 JaCoCo 工作 o字节码级别的构造函数和静态初始值设定项也算作方法。其中一些方法在 Java 源代码中可能没有直接对应关系,例如隐式生成的默认构造函数或常量初始化程序。
类
A class 当至少有一个方法被执行时被认为是已执行。请注意,JaCoCo 将构造函数和静态初始值设定项视为方法。由于 Java 接口类型可能包含静态初始值设定项,因此此类接口也被视为可执行 classes。 JaCoCo 0.6.3.20130409-1102 版权所有 © 2009、2013 Mountainminds GmbH & Co. KG 和贡献者