如何用Gradle+JaCoCo排除指定单元测试参与代码覆盖率分析?
可以实现!将指定测试排除在JaCoCo覆盖率统计之外的方案
完全可以做到让弱测试正常运行,但不纳入JaCoCo的覆盖率分析。核心思路是把测试分成两组(强测试/弱测试),分别配置执行逻辑:让强测试触发JaCoCo的覆盖率收集,弱测试只运行但不生成覆盖率数据,最后让test任务统一执行所有测试。
下面分两种常用场景给出具体配置:
方法一:用JUnit标签/分类区分测试(推荐)
这种方式最灵活,不需要依赖命名规则,只需给弱测试添加标记即可。
步骤1:标记弱测试
- JUnit 5:用
@Tag("weak")注解标记弱测试类或单个测试方法:import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @Tag("weak") public class ConsistencyCheckTest { @Test void verifyBasicConsistency() { // 你的弱测试逻辑 } } - JUnit 4:用
@Category注解,先定义一个标记接口,再标记测试:import org.junit.Test; import org.junit.experimental.categories.Category; // 定义标记接口 public interface WeakTest {} @Category(WeakTest.class) public class ConsistencyCheckTest { @Test public void verifyBasicConsistency() { // 你的弱测试逻辑 } }
步骤2:Gradle配置(Groovy DSL)
在build.gradle中添加以下配置:
plugins { id 'java' id 'jacoco' } // 1. 配置强测试任务:运行非弱测试,开启JaCoCo收集 tasks.register('strongTest', Test) { // 适配JUnit 5 useJUnitPlatform { excludeTags 'weak' } // 若用JUnit 4,替换为下面两行: // useJUnit() // excludeCategories 'com.yourpackage.WeakTest' jacoco { enabled = true // 开启覆盖率收集 } } // 2. 配置弱测试任务:只运行弱测试,关闭JaCoCo收集 tasks.register('weakTest', Test) { // 适配JUnit 5 useJUnitPlatform { includeTags 'weak' } // 若用JUnit 4,替换为下面两行: // useJUnit() // includeCategories 'com.yourpackage.WeakTest' jacoco { enabled = false // 关闭覆盖率收集 } } // 3. 让默认的test任务依赖两个子任务,运行test时执行所有测试 tasks.named('test') { dependsOn strongTest, weakTest exclude '**/*' // 禁止test任务自己执行测试,避免重复 } // 4. 配置JaCoCo报告仅基于强测试的执行数据 jacocoTestReport { executionData tasks.named('strongTest') reports { html.required = true // 生成HTML报告 xml.required = true // 生成XML报告(可选,用于CI等) } } // 让check任务自动生成覆盖率报告 tasks.named('check') { dependsOn jacocoTestReport }
步骤3:验证效果
- 运行
./gradlew test:所有测试(强+弱)都会执行,但只有强测试的覆盖数据会被JaCoCo统计。 - 运行
./gradlew jacocoTestReport:生成的报告仅包含强测试的覆盖率结果。 - 单独运行弱测试:
./gradlew weakTest
方法二:用命名规则区分测试
如果不想修改测试代码,可以通过类名规则(比如弱测试以WeakTest结尾)来分组:
plugins { id 'java' id 'jacoco' } tasks.register('strongTest', Test) { exclude '**/*WeakTest.class' // 排除弱测试类 jacoco { enabled = true } } tasks.register('weakTest', Test) { include '**/*WeakTest.class' // 仅包含弱测试类 jacoco { enabled = false } } // 后续配置和方法一一致:让test任务依赖两个子任务,配置JaCoCo报告 tasks.named('test') { dependsOn strongTest, weakTest exclude '**/*' } jacocoTestReport { executionData tasks.named('strongTest') reports { html.required = true } }
这个方案的好处是不需要改动测试代码,只要遵循命名规则即可。
内容的提问来源于stack exchange,提问作者tueda




