如何在最新版Gradle+JaCoCo中排除Kotlin数据类的测试覆盖?
排除Kotlin数据类在JaCoCo测试覆盖范围外的方法(Gradle最新版)
针对最新版Gradle和JaCoCo,有几种实用方式可以把Kotlin数据类从测试覆盖统计中排除:
1. 按包批量排除(最简便)
如果你的数据类都集中在某个特定包下(比如com.yourapp.model),直接在JaCoCo报告任务中排除整个包:
tasks.jacocoTestReport { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(it) { exclude 'com/yourapp/model/**' } })) }
2. 排除所有带@Data注解的类
Kotlin数据类都会被自动标记@kotlin.Data注解,通过检查类文件中的这个注解来批量排除所有数据类:
tasks.withType(JacocoReport).configureEach { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(it) { // 同时排除数据类自动生成的序列化器(可选) exclude '**/*$$serializer.class' // 过滤带有@Data注解的类 exclude { file -> new File(file.absolutePath).text.contains('Lkotlin/Data;') } } })) }
3. 自定义注解灵活排除
如果只需要排除部分数据类,可以自定义一个排除注解,给目标数据类标记后再配置JaCoCo:
第一步:创建排除注解
@Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.CLASS) annotation class ExcludeFromCoverage
第二步:给数据类添加注解
@ExcludeFromCoverage data class User(val id: Long, val name: String)
第三步:配置Gradle排除带注解的类
tasks.withType(JacocoReport).configureEach { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(it) { exclude { file -> try { // 解析类全限定名 val classPath = file.absolutePath .replace('\\', '/') .split('/classes/kotlin/main/')[1] .replace('.class', '') .replace('/', '.') // 检查类是否带有自定义排除注解 Class.forName(classPath).isAnnotationPresent(ExcludeFromCoverage::class.java) } catch (e: Exception) { false } } } })) }
注意:如果使用Gradle 8.x及以上版本,配置语法可能略有调整,确保同步项目后验证JaCoCo报告是否生效。
内容的提问来源于stack exchange,提问作者Darkin Rall
相关产品推荐
相关产品推荐

