通过执行 JAR 应用程序生成 JaCoCo 覆盖率报告
Generating JaCoCo coverage report by executing JAR application
我正在开发一个控制台 Java 应用程序 (CLI) 并尝试通过执行该程序来编写一些黑盒测试,检查输出并将其与预期的结果进行比较(使用 JUnit)。
一切正常,但我无法从 JaCoCo 获取代码覆盖率报告。
我的 build.gradle
文件中的 JaCoCo 和 JUnit 配置:
...
plugins {
id 'jacoco'
}
...
dependencies {
...
testCompile('org.junit.jupiter:junit-jupiter:5.5.2')
}
test {
useJUnitPlatform()
}
jacoco {
toolVersion = "0.8.5"
reportsDir = file("$buildDir/reports")
}
jacocoTestReport {
reports {
xml.enabled true
csv.enabled false
xml.destination file("${buildDir}/coverage.xml")
}
getExecutionData().setFrom("$buildDir/jacoco/test.exec")
}
在测试中我这样做:
String command = "java -javaagent:libs/jacocoagent.jar=destfile=build/jacoco/test.exec -jar build/libs/myapp.jar";
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
InputStream inputStream = process.getInputStream();
byte[] b = new byte[inputStream.available()];
String cliOutput = new String(b);
在测试执行文件 build/jacoco/test.exec
和 build/coverage.xml
之后创建,但不包含任何覆盖率信息。
对于简单的单元测试,正在生成覆盖率,但它不包括执行上述整个程序的覆盖率。
更新:
我还尝试了另一种方法 运行 JAR:
List<String> args = new ArrayList<>();
args.add("java");
args.add("-javaagent:libs/jacocoagent.jar=destfile=build/jacoco/test.exec");
args.add("-jar");
args.add(this.getCLiPath());
args.add(command);
ProcessBuilder builder = new ProcessBuilder(args.toArray(new String[0]));
Process process = builder.start();
但这并没有帮助,同样的结果 - 执行 JAR 没有覆盖。
UPD 2: 我刚刚发现执行数据正在收集到 .exec
文件中。
但是在报告生成过程中(在 Gradle 任务 jacocoTestReport
中)跳过了此数据,并显示错误消息 [ant:jacocoReport] Execution data for class ... does not match.
。
这是我从 jar 文件中得到的执行数据,但由于某种原因,它在报告中被跳过了。
我终于找到了解决方案,所以我需要记录下来。
错误与 classID 有关。这是 JaCoCo 文档站点上详细描述的概念 - Class Ids。在已编译的应用程序中 class ID 不同,JaCoCo 无法处理。
此 question. This answer 中的更多详细信息帮助我解决了 ant:jacocoReport
个错误。
此外,我需要修复我的 CI/CD。我正在使用 Azure DevOps 管道。
我的 Gradle 管道中的任务:
- task: Gradle@2
displayName: 'Gradle build, tests, code coverage report'
inputs:
gradleWrapperFile: 'gradlew'
gradleOptions: '-Xmx3072m'
javaHomeOption: 'JDKVersion'
jdkVersionOption: '1.8'
jdkArchitectureOption: 'x64'
publishJUnitResults: true
testResultsFiles: '**/TEST-*.xml'
tasks: 'doJacocoOfflineInstrumentation buildCliJar test jacocoTestReport'
我正在开发一个控制台 Java 应用程序 (CLI) 并尝试通过执行该程序来编写一些黑盒测试,检查输出并将其与预期的结果进行比较(使用 JUnit)。 一切正常,但我无法从 JaCoCo 获取代码覆盖率报告。
我的 build.gradle
文件中的 JaCoCo 和 JUnit 配置:
...
plugins {
id 'jacoco'
}
...
dependencies {
...
testCompile('org.junit.jupiter:junit-jupiter:5.5.2')
}
test {
useJUnitPlatform()
}
jacoco {
toolVersion = "0.8.5"
reportsDir = file("$buildDir/reports")
}
jacocoTestReport {
reports {
xml.enabled true
csv.enabled false
xml.destination file("${buildDir}/coverage.xml")
}
getExecutionData().setFrom("$buildDir/jacoco/test.exec")
}
在测试中我这样做:
String command = "java -javaagent:libs/jacocoagent.jar=destfile=build/jacoco/test.exec -jar build/libs/myapp.jar";
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
InputStream inputStream = process.getInputStream();
byte[] b = new byte[inputStream.available()];
String cliOutput = new String(b);
在测试执行文件 build/jacoco/test.exec
和 build/coverage.xml
之后创建,但不包含任何覆盖率信息。
对于简单的单元测试,正在生成覆盖率,但它不包括执行上述整个程序的覆盖率。
更新: 我还尝试了另一种方法 运行 JAR:
List<String> args = new ArrayList<>();
args.add("java");
args.add("-javaagent:libs/jacocoagent.jar=destfile=build/jacoco/test.exec");
args.add("-jar");
args.add(this.getCLiPath());
args.add(command);
ProcessBuilder builder = new ProcessBuilder(args.toArray(new String[0]));
Process process = builder.start();
但这并没有帮助,同样的结果 - 执行 JAR 没有覆盖。
UPD 2: 我刚刚发现执行数据正在收集到 .exec
文件中。
但是在报告生成过程中(在 Gradle 任务 jacocoTestReport
中)跳过了此数据,并显示错误消息 [ant:jacocoReport] Execution data for class ... does not match.
。
这是我从 jar 文件中得到的执行数据,但由于某种原因,它在报告中被跳过了。
我终于找到了解决方案,所以我需要记录下来。
错误与 classID 有关。这是 JaCoCo 文档站点上详细描述的概念 - Class Ids。在已编译的应用程序中 class ID 不同,JaCoCo 无法处理。
此 question. This answer 中的更多详细信息帮助我解决了 ant:jacocoReport
个错误。
此外,我需要修复我的 CI/CD。我正在使用 Azure DevOps 管道。
我的 Gradle 管道中的任务:
- task: Gradle@2
displayName: 'Gradle build, tests, code coverage report'
inputs:
gradleWrapperFile: 'gradlew'
gradleOptions: '-Xmx3072m'
javaHomeOption: 'JDKVersion'
jdkVersionOption: '1.8'
jdkArchitectureOption: 'x64'
publishJUnitResults: true
testResultsFiles: '**/TEST-*.xml'
tasks: 'doJacocoOfflineInstrumentation buildCliJar test jacocoTestReport'