我正在尝试建立一个过程,以收集质量检查测试的覆盖率并将此信息汇总到单个报告中。我们有一个庞大的团队,代码更改非常频繁,因此我的主要问题与无法从单个应用程序版本收集覆盖范围有关。根据文档,Jococo应该警告执行数据不匹配的所有类,并将其报告为未涵盖。
[WARN] Execution data for class com/application/package/ClassName does not match.
相关文档:
但是,当我合并从不同版本的应用程序收集到的exec文件时(总共几百万行代码,成千上万个更改的行),Jacoco报告了WARN仅涉及四个类,导致了12行代码。用于报告的JAR文件取自合并的最新版本。
因此,我只是想了解这是可能的,以及我是否可以信任此报告?
答案 0 :(得分:2)
请考虑以下示例。
版本1包含以下源文件:
src/Example.java
class Example {
public static void main(String[] args) {
C.print(A.getPrefix() + B.getSuffix());
}
}
src/A.java
class A {
static String getPrefix() {
return "Hello, ";
}
}
src/B.java
class B {
static String getSuffix() {
return "World";
}
}
src/C.java
class C {
static void print(String msg) {
if ("Hello, World".equals(msg)) {
System.out.println(msg + "!");
} else {
System.out.println(msg);
}
}
}
让我们编译并执行版本1:
# javac src/A.java src/B.java src/C.java src/Example.java -d v1
# java \
-javaagent:jacoco-0.8.4/lib/jacocoagent.jar=destfile=1.exec,sessionid=v1 \
-cp v1 \
Example
Hello, World!
版本2:
src/Example.java
已修改
class Example {
public static void main(String[] args) {
C.print("Hello");
}
}
src/A.java
已修改
class A {
static String getPrefix() {
return "";
}
}
src/B.java
和src/C.java
未修改
让我们编译并执行版本2:
# javac src/A.java src/B.java src/C.java src/Example.java -d v2
# java \
-javaagent:jacoco-0.8.4/lib/jacocoagent.jar=destfile=2.exec,sessionid=v2 \
-cp v2 \
Example
Hello
请注意,Example.class
和A.class
是不同的,而B.class
和C.class
在两个版本中是相同的:
# diff --report-identical-files v1/Example.class v2/Example.class
Binary files v1/Example.class and v2/Example.class differ
# diff --report-identical-files v1/A.class v2/A.class
Binary files v1/A.class and v2/A.class differ
# diff --report-identical-files v1/B.class v2/B.class
Files v1/B.class and v2/B.class are identical
# diff --report-identical-files v1/C.class v2/C.class
Files v1/C.class and v2/C.class are identical
因此为这些类文件计算了id:
# java -jar jacoco-0.8.4/lib/jacococli.jar classinfo v1
INST BRAN LINE METH CXTY ELEMENT
8 0 3 2 2 class 0xa170badd641f5a31 Example
5 0 2 2 2 class 0x45b9146c94e31f23 B
5 0 2 2 2 class 0xb8f01b5012761c26 A
16 2 5 2 3 class 0xaf857eca353b9073 C
# java -jar jacoco-0.8.4/lib/jacococli.jar classinfo v2
INST BRAN LINE METH CXTY ELEMENT
6 0 3 2 2 class 0x5915f0accdd77c81 Example
5 0 2 2 2 class 0x45b9146c94e31f23 B
5 0 2 2 2 class 0xa529ea9ab9745b77 A
16 2 5 2 3 class 0xaf857eca353b9073 C
因此id记录在执行数据中:
# java -jar jacoco-0.8.4/lib/jacococli.jar execinfo 1.exec
[INFO] Loading exec file 1.exec.
CLASS ID HITS/PROBES CLASS NAME
Session "v1": Fri Jul 05 20:39:50 CEST 2019 - Fri Jul 05 20:39:50 CEST 2019
b8f01b5012761c26 1 of 2 A
a170badd641f5a31 1 of 2 Example
45b9146c94e31f23 1 of 2 B
af857eca353b9073 3 of 5 C
# java -jar jacoco-0.8.4/lib/jacococli.jar execinfo 2.exec
[INFO] Loading exec file 2.exec.
CLASS ID HITS/PROBES CLASS NAME
Session "v2": Fri Jul 05 20:39:50 CEST 2019 - Fri Jul 05 20:39:50 CEST 2019
af857eca353b9073 2 of 5 C
5915f0accdd77c81 1 of 2 Example
让我们合并一下,它将合并具有相同名称和相同ID的类的执行数据:
# java -jar jacoco-0.8.4/lib/jacococli.jar merge 1.exec 2.exec --destfile merged.exec
[INFO] Loading execution data file /private/tmp/j/1.exec.
[INFO] Loading execution data file /private/tmp/j/2.exec.
[INFO] Writing execution data to /private/tmp/j/merged.exec.
# java -jar jacoco-0.8.4/lib/jacococli.jar execinfo merged.exec
[INFO] Loading exec file merged.exec.
CLASS ID HITS/PROBES CLASS NAME
Session "v1": Fri Jul 05 20:39:50 CEST 2019 - Fri Jul 05 20:39:50 CEST 2019
Session "v2": Fri Jul 05 20:39:50 CEST 2019 - Fri Jul 05 20:39:50 CEST 2019
b8f01b5012761c26 1 of 2 A
a170badd641f5a31 1 of 2 Example
45b9146c94e31f23 1 of 2 B
af857eca353b9073 4 of 5 C
5915f0accdd77c81 1 of 2 Example
让我们使用合并的执行数据和版本2的类文件生成报告
# java \
-jar jacoco-0.8.4/lib/jacococli.jar \
report merged.exec \
--classfiles v2 \
--sourcefiles src \
--html report
[INFO] Loading execution data file /private/tmp/j/merged.exec.
[WARN] Some classes do not match with execution data.
[WARN] For report generation the same class files must be used as at runtime.
[WARN] Execution data for class A does not match.
[INFO] Analyzing 4 classes.
对于src/Example.java
,报告将显示有关版本2执行的数据,因为v2/Example.class
的ID为5915f0accdd77c81
:
对于src/A.java
,报告将不会显示任何内容,因为在merged.exec
中没有与v2/A.class
的ID相对应的数据,即a529ea9ab9745b77
:
带有类似于报告生成过程中警告的消息
对于src/B.java
,报告将显示有关版本1执行的数据,因为在merged.exec
中,来自1.exec
的数据对应于v2/B.class
-{{1}的ID }:
对于45b9146c94e31f23
,报告将显示有关两个版本执行情况的组合数据,因为在src/C.java
中,来自merged.exec
和1.exec
的数据都与{{ 1}}-2.exec
:
从一定意义上来说,以上报告是正确的,因为它完全正确地代表了针对生成报告而提供的各个类文件的两个执行的合并:
v2/C.class
已执行af857eca353b9073
未执行v2/Example.class
在版本1中执行v2/A.class
中的两个分支均已执行-版本1中的一个分支,版本2中的另一个分支如果不使用类ID报告,将无法完全检测到
B.class
将被视为已执行,但从未发生C.class
中的但是,对于所有类别,以上报告并不代表最终版本,因为在最终版本中
v2/A.class
将永远不会执行A.java
中仅一个分支将被执行答案 1 :(得分:0)