JaCoCo 是一个用于计算 Java 代码覆盖率的工具,它可以测量单元测试覆盖了代码的哪些部分。JaCoCo官网:EclEmma - JaCoCo Java Code Coverage Library
目录
1. JaCoCo 基本用法
2.JaCoCo 集成到构建流程
3.设置 JaCoCo 覆盖率目标
4.集成到现有测试框架
5.生成详细的覆盖率报告
6.跨多个测试运行的覆盖率聚合
7.JaCoCo在词序集成(CI)中的应用
8.设置代码覆盖率的排除和包含规则
9.分布式测试覆盖率收集
10.代码覆盖率的增量分析
11.代码覆盖率的分支覆盖分析
12.在Maven中的详细配置示例
1. JaCoCo 基本用法
步骤 | 描述 | 命令 |
---|---|---|
1 | 添加 JaCoCo 插件到项目 | 在 pom.xml 或 build.gradle 文件中添加 JaCoCo 插件 |
2 | 配置 JaCoCo 插件 | 设置 JaCoCo 插件的配置,如输出目录 |
3 | 执行测试并生成报告 | 使用 JaCoCo 插件执行测试,并生成覆盖率报告 |
4 | 查看报告 | 查看生成的 HTML 报告,了解代码覆盖率 |
代码示例:
Maven方式;在pom.xml文件中添加 JaCoCo 插件:
<build><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><executions><execution><goals><goal>prepare-agent</goal></goals></execution><execution><id>report</id><phase>test</phase><goals><goal>report</goal></goals></execution></executions></plugin></plugins>
</build>
执行测试并生成报告:
mvn test jacoco:report
Gradle方式;
在 build.gradle
文件中添加 JaCoCo 插件:
plugins {id 'jacoco'
}jacoco {toolVersion = "0.8.7"
}test {useJUnitPlatform()
}tasks.test {finalizedBy jacocoTestReport
}
执行测试并生成报告:
gradle test jacocoTestReport
查看报告:
打开生成的 index.html
文件
2.JaCoCo 集成到构建流程
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 集成到构建脚本 | 将 JaCoCo 集成到项目的构建脚本中,确保每次构建都运行测试并生成覆盖率报告 | Maven: <build>...</build> 或 Gradle: buildscript {...} |
2 | 自动化测试执行 | 在持续集成(CI)服务器上配置自动化测试执行,使用 JaCoCo 插件 | CI 配置文件中添加 JaCoCo 插件配置 |
3 | 报告的存档 | 将生成的覆盖率报告存档,以便历史比较和分析 | 使用 CI 工具的归档功能,如 archiveArtifacts |
4 | 报告的查看 | 在 CI 服务器上查看覆盖率报告,或将报告部署到服务器供团队查看 | 在 CI 服务器的 Web 界面查看或通过 Web 服务器访问 |
代码示例:
Maven中配置;
在 pom.xml
中集成 JaCoCo 并配置 CI 插件(例如 Jenkins):
<build><plugins><!-- JaCoCo plugin configuration from previous example --><!-- ... --></plugins>
</build><reporting><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version></plugin></plugins>
</reporting>
gradle中;在 build.gradle
中集成 JaCoCo 并配置 CI 插件(例如 Jenkins):
// JaCoCo plugin configuration from previous example
// ...// Example of Jenkins pipeline configuration
task jacocoReport(type: JacocoReport, dependsOn: test) {executionData testreports {xml.enabled truehtml.enabled true}
}// Jenkins might automatically call this task as part of the pipeline
在CI服务器上,你可能需要配置一些步骤来确保JaCoCo报告被正确生成和存档。例如,在Jenkins中,你可以使用archiveArtifacts
步骤:
pipeline {agent anystages {stage('Build') {steps {// Build and test stepssh 'mvn clean package jacoco:report'}}stage('Archive') {steps {// Archive JaCoCo reportsarchiveArtifacts artifacts: '**/jacoco.exec', fingerprint: true}}}post {always {// Clean up workspacecleanWs()}}
}
这只是一个基本的示例,实际的CI配置将取决于你使用的CI工具和你的具体需求。
3.设置 JaCoCo 覆盖率目标
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 定义覆盖率目标 | 为项目设置覆盖率目标,如至少80%的行覆盖率 | 在 JaCoCo 插件配置中指定目标 |
2 | 配置 JaCoCo 插件 | 配置 JaCoCo 插件以检查覆盖率是否达到目标 | Maven: <configuration>...</configuration> 或 Gradle: jacoco {...} |
3 | 测试覆盖率检查 | 在构建过程中执行覆盖率检查,确保测试覆盖率满足目标 | Maven: <goal>check</goal> 或 Gradle: tasks.check.dependsOn jacocoTestReport |
4 | 查看失败的构建 | 如果覆盖率未达到目标,构建将失败,查看失败原因并改进测试 | 查看构建日志中的 JaCoCo 报告部分 |
代码示例:
Maven中; 在 pom.xml
中配置 JaCoCo 插件以设置覆盖率目标:
<build><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><executions><!-- ... --></executions><configuration><rules><rule><element>BUNDLE</element><limits><limit><counter>LINE</counter><value>COVEREDRATIO</value><minimum>0.80</minimum></limit></limits></rule></rules></configuration></plugin></plugins>
</build>
执行测试并检查覆盖率:
mvn test jacoco:check
在Gradle中; 在 build.gradle
中配置 JaCoCo 插件以设置覆盖率目标:
plugins {id 'jacoco'
}jacoco {toolVersion = "0.8.7"minimumCoverage = 0.80
}check.dependsOn jacocoTestReport
执行测试并检查覆盖率:
gradle check
通过设置覆盖率目标,你可以确保项目在每次构建时都达到一定的质量标准。如果覆盖率未达到目标,构建将失败,从而提醒开发团队需要改进测试。
4.集成到现有测试框架
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 选择测试框架 | 确定项目中使用的测试框架,如 JUnit, TestNG | - |
2 | 配置 JaCoCo 以支持测试框架 | 确保 JaCoCo 插件与测试框架兼容 | Maven/Gradle 插件配置中通常自动兼容 |
3 | 执行测试 | 使用测试框架执行测试用例 | 命令行或 IDE 中运行测试 |
4 | 生成覆盖率报告 | 测试完成后,使用 JaCoCo 生成覆盖率报告 | Maven: mvn jacoco:report 或 Gradle: gradle jacocoTestReport |
代码示例
对于大多数流行的测试框架,JaCoCo 的集成通常是透明的,不需要特别的配置。以下是一些常见测试框架的集成示例。
如果你的项目使用 JUnit 或者TestNG作为测试框架,JaCoCo 将自动处理 JUnit和TestNG 测试的覆盖率。
执行测试和生成报告的 Maven 命令:
mvn test jacoco:report
Gradle 命令:
gradle test jacocoTestReport
在大多数情况下,JaCoCo 插件会自动检测到项目中使用的测试框架,并相应地生成覆盖率报告。如果需要对测试框架进行特别配置,官方文档会提供详细的指导。
5.生成详细的覆盖率报告
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 配置 JaCoCo 插件 | 设置 JaCoCo 插件以生成不同类型的覆盖率报告 | 在构建脚本中配置 jacoco 插件 |
2 | 执行测试 | 运行测试用例,JaCoCo 会收集覆盖数据 | 使用 Maven 或 Gradle 运行测试命令 |
3 | 生成报告 | 使用 JaCoCo 命令生成覆盖率报告 | Maven: mvn jacoco:report 或 Gradle: gradle jacocoTestReport |
4 | 查看报告 | 分析生成的报告,了解代码的覆盖率情况 | 打开生成的 HTML 报告文件 |
代码示例
Maven中;在 pom.xml
中配置 JaCoCo 插件以生成详细的覆盖率报告:
<build><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><executions><!-- ... --></executions><configuration><!-- 配置覆盖率报告的输出目录 --><dataFile>target/jacoco.exec</dataFile><outputDirectory>target/jacoco-reports</outputDirectory></configuration></plugin></plugins>
</build>
执行测试并生成报告:
mvn test jacoco:report
Gradle中; 在 build.gradle
中配置 JaCoCo 插件以生成详细的覆盖率报告:
plugins {id 'jacoco' // 确保已经添加了 JaCoCo 插件
}jacoco {toolVersion = "0.8.7"
}test {useJUnitPlatform()
}tasks.jacocoTestReport {reports {// 配置 HTML 和 XML 报告的输出html.enabled truexml.enabled true}
}// 将测试报告任务添加到构建生命周期中
check.dependsOn jacocoTestReport
JaCoCo 支持多种报告格式,包括 HTML、XML 和 CSV。HTML 报告通常用于可视化代码覆盖率,而 XML 报告可以用于自动化分析和集成到 CI 系统中。
6.跨多个测试运行的覆盖率聚合
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 执行多个测试运行 | 执行多个测试套件或测试运行,以覆盖不同的代码路径 | 使用测试框架执行测试 |
2 | 收集覆盖率数据 | 收集每次测试运行的覆盖率数据文件(.exec) | JaCoCo 插件自动生成 .exec 文件 |
3 | 聚合覆盖率数据 | 使用 JaCoCo 命令行工具或 Maven/Gradle 插件聚合多个 .exec 文件 | JaCoCo CLI: java -jar jacococli.jar merge |
4 | 生成聚合报告 | 从聚合后的覆盖率数据生成报告 | Maven: mvn jacoco:report-aggregate 或 JaCoCo CLI |
代码示例使用JaCoCo CLI聚合覆盖率数据
首先,确保你已经收集了多个 .exec
文件。然后使用 JaCoCo 的命令行工具进行聚合:
java -jar jacococli.jar merge *.exec merged.exec
这会将所有 .exec
文件合并成一个名为 merged.exec
的文件。
Maven生成集合报告
在 pom.xml
中配置 JaCoCo 插件以使用聚合的覆盖率数据生成报告:
<build><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><executions><execution><id>default-merge</id><phase>verify</phase><goals><goal>merge</goal></goals><configuration><fileSets><fileSet><directory>${project.build.directory}</directory><includes><include>*.exec</include></includes></fileSet></fileSets><destFile>${project.build.directory}/jacoco-merged.exec</destFile></configuration></execution><execution><id>default-report</id><phase>verify</phase><goals><goal>report-aggregate</goal></goals></execution></executions></plugin></plugins>
</build>
执行聚合和报告生成:
mvn jacoco:merge jacoco:report-aggregate
Gradle生成聚合报告
在 build.gradle
中配置 JaCoCo 插件以使用聚合的覆盖率数据生成报告:
plugins {id 'jacoco'
}tasks.register('mergeJacocoReports', JacocoMerge) {executionData files('build/jacoco/*.exec')destinationFile file("$buildDir/jacoco/merged.exec")
}tasks.jacocoTestReport.dependsOn 'mergeJacocoReports'
通过聚合多个测试运行的覆盖率数据,你可以获得更全面的代码覆盖率视图,这对于大型项目或需要运行多个测试套件的场景非常有用。
7.JaCoCo在词序集成(CI)中的应用
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 配置 CI 环境 | 在 CI 服务器上安装 Java 和 JaCoCo 插件 | 根据 CI 服务器的文档进行安装 |
2 | 编写构建脚本 | 创建或修改 CI 项目的构建脚本,以集成 JaCoCo 插件 | CI 项目的 .yml 或其他配置文件 |
3 | 执行测试并生成报告 | 在 CI 构建过程中执行测试,并使用 JaCoCo 生成覆盖率报告 | CI 构建脚本中的测试执行命令 |
4 | 上传报告 | 将 JaCoCo 生成的覆盖率报告上传到 CI 服务器或外部存储 | 使用 CI 服务器的归档或上传功能 |
5 | 分析报告 | 在 CI 服务器上分析覆盖率报告,确保代码覆盖率达标 | 查看 CI 服务器提供的报告链接 |
代码示例:
Jenkins中配置(使用Pipeline)
在 Jenkins 中,你可以使用 Pipeline 功能来集成 JaCoCo。以下是一个 Jenkinsfile 的示例:
pipeline {agent anystages {stage('Checkout') {steps {// 检出代码git 'https://gitlab_ip:port/your/repo.git'}}stage('Test') {steps {// 使用 Maven 或 Gradle 执行测试并生成 JaCoCo 报告sh 'mvn clean test jacoco:report'}}stage('Archive') {steps {// 归档 JaCoCo 报告archiveArtifacts artifacts: 'target/site/jacoco/*.html', fingerprint: true}}}post {always {// 无论构建成功与否,都执行清理操作cleanWs()}}
}
在 CI 过程中集成 JaCoCo 可以帮助团队持续监控代码的测试覆盖率,确保代码质量,并在代码合并到主分支之前发现潜在的未测试覆盖的代码区域。
8.设置代码覆盖率的排除和包含规则
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 确定覆盖率规则 | 确定哪些代码应该被包含或排除在覆盖率报告之外 | - |
2 | 配置 JaCoCo 插件 | 在构建脚本中配置 JaCoCo 插件以应用包含和排除规则 | Maven/Gradle 插件配置 |
3 | 执行测试 | 运行测试用例,JaCoCo 将根据规则收集覆盖数据 | Maven: mvn test 或 Gradle: gradle test |
4 | 生成报告 | 使用 JaCoCo 生成覆盖率报告,报告将遵循配置的规则 | Maven: mvn jacoco:report 或 Gradle: gradle jacocoTestReport |
代码示例:
在 pom.xml
中配置 JaCoCo 插件以设置包含和排除规则:
<build><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><configuration><includes><include>com/mycompany/**</include></includes><excludes><exclude>com/mycompany/**/internal/*</exclude><exclude>com/mycompany/**/*Test</exclude></excludes></configuration></plugin></plugins>
</build>
在Gradle中;
在 build.gradle
中配置 JaCoCo 插件以设置包含和排除规则:
plugins {id 'jacoco'
}jacoco {// 配置包含规则include "**/com/mycompany/**/*.class"// 配置排除规则exclude "**/com/mycompany/**/internal/**/*.class"exclude "**/com/mycompany/**/*Test.class"
}test {// 确保测试任务完成后生成 JaCoCo 报告useJUnitPlatform()finalizedBy jacocoTestReport
}
通过设置包含和排除规则,你可以专注于对重要业务逻辑的测试覆盖率,同时忽略那些不需要或不值得测试的代码,如自动生成的代码、测试代码本身、内部工具类等。
9.分布式测试覆盖率收集
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 配置分布式测试环境 | 确保测试可以在多个分布式节点上执行 | CI/CD 配置或分布式测试工具配置 |
2 | 收集单个节点的覆盖率数据 | 每个测试节点独立运行测试并生成 .exec 文件 | 使用 Maven 或 Gradle 在每个节点上执行测试 |
3 | 合并分布式节点的覆盖率数据 | 使用 JaCoCo 命令行工具或插件合并所有节点的 .exec 文件 | JaCoCo CLI: java -jar jacococli.jar merge |
4 | 生成合并后的覆盖率报告 | 从合并后的覆盖率数据生成最终的覆盖率报告 | Maven: mvn jacoco:report-aggregate 或 JaCoCo CLI |
代码示例
分布式测试环境配置
在分布式测试环境中,每个测试节点通常会独立执行测试。确保每个节点的 JaCoCo .exec
文件都被保存并可以在之后被合并。
Maven合并分布式节点的覆盖率数据
在 Maven 中,你可以使用 JaCoCo 的 merge
目标来合并所有节点的 .exec
文件:
mvn jacoco:merge@merge-reports -Djacoco.merge.dataFile1=<node1-jacoco-exec-file-path>
其中 <node1-jacoco-exec-file-path>
是第一个节点生成的 .exec
文件的路径。如果有更多节点,可以使用 -Djacoco.merge.dataFile2
、-Djacoco.merge.dataFile3
等来指定。
JaCoCo CLI合并分布式节点的覆盖率数据
使用 JaCoCo 的命令行工具合并所有节点的 .exec
文件:
java -jar jacococli.jar merge node1.exec node2.exec merged.exec
这会生成一个名为 merged.exec
的文件,其中包含了所有测试节点的覆盖率数据。
生成合并后的覆盖率报告
一旦你有了合并后的 .exec
文件,就可以使用 JaCoCo 生成最终的覆盖率报告:
对于 Maven:
mvn jacoco:report-aggregate@aggregate-reports -Djacoco.report-aggregate.dataFile=merged.exec
对于 JaCoCo CLI,报告生成通常是通过 Maven 或 Gradle 插件完成的。
在分布式测试环境中,覆盖率数据的合并是确保获得整个应用代码覆盖率视图的关键步骤。
10.代码覆盖率的增量分析
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 收集初始覆盖率数据 | 运行测试用例并收集初始的代码覆盖率数据 | 使用 Maven 或 Gradle 执行测试 |
2 | 执行代码变更 | 对代码进行修改或增加新功能 | 修改源代码 |
3 | 重新收集覆盖率数据 | 在变更后再次运行测试并收集覆盖率数据 | 使用 Maven 或 Gradle 执行测试 |
4 | 进行增量分析 | 比较两次测试运行的覆盖率数据,找出变更影响的范围 | 使用 JaCoCo 的增量分析功能 |
5 | 查看增量报告 | 分析增量报告,了解新增或遗漏的覆盖区域 | 查看 JaCoCo 生成的增量报告 |
代码示例
在 Maven 中,你可以使用 JaCoCo 插件的 prepare-agent
阶段来配置初始的覆盖率数据收集:
<plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><executions><execution><goals><goal>prepare-agent</goal><goal>report</goal></goals></execution></executions>
</plugin>
然后,进行代码变更并再次运行测试:
mvn test jacoco:report
在 Gradle 中,JaCoCo 插件会自动配置测试覆盖率的收集:
plugins {id 'jacoco'
}test {useJUnitPlatform()
}tasks.jacocoTestReport {dependsOn test
}
执行测试:
gradle test jacocoTestReport
增量分析
aCoCo 支持增量分析,但需要手动比较不同测试运行生成的 .exec
文件。你可以使用 JaCoCo 的命令行工具或自定义脚本来比较这些文件,找出新增加的测试覆盖或遗漏的覆盖区域。
java -jar jacococli.jar diff old.exec new.exec
增量分析有助于开发人员理解他们的代码变更如何影响测试覆盖率,从而更精确地评估变更对测试覆盖的影响。
11.代码覆盖率的分支覆盖分析
步骤 | 描述 | 命令 | 说明 |
---|---|---|---|
1 | 配置 JaCoCo 插件 | 确保 JaCoCo 插件配置为收集分支覆盖数据 | 在构建脚本中设置 dataFormat 为 BINARY 或 XML |
2 | 执行测试 | 运行测试用例,JaCoCo 将收集包括分支覆盖在内的覆盖数据 | 使用 Maven 或 Gradle 执行测试命令 |
3 | 生成分支覆盖报告 | 使用 JaCoCo 命令或插件生成分支覆盖报告 | Maven: mvn jacoco:report 或 Gradle: gradle jacocoTestReport |
4 | 查看报告 | 分析生成的报告,特别关注分支覆盖率 | 打开 HTML 报告中的“Branches”部分 |
代码示例
在 pom.xml
中配置 JaCoCo 插件以收集分支覆盖数据:
<build><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><configuration><dataFormat>XML</dataFormat></configuration><executions><!-- ... --></executions></plugin></plugins>
</build>
执行测试并生成报告:
mvn test jacoco:report
在 build.gradle
中配置 JaCoCo 插件以收集分支覆盖数据:
plugins {id 'jacoco'
}jacoco {toolVersion = "0.8.7"
}test {useJUnitPlatform()
}tasks.jacocoTestReport {reports {xml.enabled = truehtml.enabled = true}dependsOn test
}
执行测试并生成报告:
gradle test jacocoTestReport
分支覆盖率是衡量测试质量的一个重要指标,它显示了测试用例是否覆盖了所有的逻辑分支。JaCoCo 的分支覆盖报告可以帮助开发人员识别未被测试覆盖的代码路径,从而提高测试的全面性。
还有行覆盖率分析在html报告中的"Lines"部分;指令覆盖率分析在报告的“Instructions”部分;限定条件覆盖分析在报告的“Conditions”部分,还有类覆盖率和包覆盖率分析等。
12.在Maven中的详细配置示例
接下来给一个相对比较详细完整的JaCoCo在Maven中的配置;
<project><!-- ... other configurations ... --><build><plugins><!-- JaCoCo Maven Plugin Configuration --><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><executions><!-- Prepare JaCoCo agent before integration-test phase --><execution><id>pre-unit-test</id><goals><goal>prepare-agent</goal></goals><configuration><!-- Sets the path to the file which will contain the execution data --><destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile><propertyName>surefireArgLine</propertyName></configuration></execution><!-- Generate coverage report after integration-test phase --><execution><id>post-unit-test</id><phase>test</phase><goals><goal>report</goal></goals><configuration><!-- Sets the path to the file which will contain the execution data --><dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile><!-- Output directory for the reports --><outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory></configuration></execution><!-- Example of integration test coverage --><execution><id>pre-integration-test</id><phase>pre-integration-test</phase><goals><goal>prepare-agent</goal></goals><configuration><!-- Pass the property to surefire via system property --><propertyName>failsafeArgLine</propertyName></configuration></execution><execution><id>post-integration-test</id><phase>post-integration-test</phase><goals><goal>report</goal></goals><configuration><dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile><outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory></configuration></execution></executions><configuration><!-- Specify the rules --><rules><rule><element>BUNDLE</element><limits><limit><counter>COMPLEXITY</counter><value>COVEREDRATIO</value><minimum>0.60</minimum></limit></limits></rule></rules></configuration></plugin></plugins></build><!-- ... other configurations ... -->
</project>
在这个配置中:
prepare-agent
用于在测试执行前准备 JaCoCo 代理。report
用于在测试执行后生成覆盖率报告。destFile
指定了 JaCoCo 代理生成的执行数据文件的位置。propertyName
指定了包含 JaCoCo 配置的系统属性名称,这个属性会被传递给测试插件。rules
部分定义了覆盖率规则,这里设置了一个复杂度覆盖率的最低阈值。outputDirectory
指定了覆盖率报告的输出目录。
请注意,这个配置是一个示例,实际的配置可能需要根据项目的特定需求进行调整。此外,版本号 0.8.7
应该替换为 JaCoCo 插件的最新版本。在实际应用中,你可能还需要配置 surefire-plugin
和 failsafe-plugin
以确保它们使用 JaCoCo 提供的系统属性来执行测试。