我正在尝试在多模块 Android 项目中使用 jacoco。该项目类似于 NowInAndroid。 Jacoco.kt 文件是相同的:
private val coverageExclusions = listOf(
// Android
"**/R.class",
"**/R\$*.class",
"**/BuildConfig.*",
"**/Manifest*.*",
"**/*_Hilt*.class",
"**/Hilt_*.class",
)
private fun String.capitalize() = replaceFirstChar {
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
}
internal fun Project.configureJacoco(
androidComponentsExtension: AndroidComponentsExtension<*, *, *>
) {
configure<JacocoPluginExtension> {
toolVersion = "0.8.7"
}
androidComponentsExtension.onVariants { variant ->
val myObjFactory = project.objects
val buildDir = layout.buildDirectory.get().asFile
val allJars: ListProperty<RegularFile> = myObjFactory.listProperty(RegularFile::class.java)
val allDirectories: ListProperty<Directory> = myObjFactory.listProperty(Directory::class.java)
val reportTask =
tasks.register("create${variant.name.capitalize()}CombinedCoverageReport", JacocoReport::class) {
classDirectories.setFrom(
allJars,
allDirectories.map { dirs ->
dirs.map { dir ->
myObjFactory.fileTree().setDir(dir).exclude(coverageExclusions)
}
}
)
reports {
xml.required.set(true)
html.required.set(true)
}
// TODO: This is missing files in src/debug/, src/prod, src/demo, src/demoDebug...
sourceDirectories.setFrom(files("$projectDir/src/main"))
println("This is the projectDir -> ${projectDir}")
executionData.setFrom(
project.fileTree("$buildDir/outputs/unit_test_code_coverage/${variant.name}UnitTest")
.matching { include("**/*.exec") },
project.fileTree("$buildDir/outputs/code_coverage/${variant.name}AndroidTest")
.matching { include("**/*.ec") }
)
}
variant.artifacts.forScope(ScopedArtifacts.Scope.PROJECT)
.use(reportTask)
.toGet(
ScopedArtifact.CLASSES,
{ _ -> allJars },
{ _ -> allDirectories },
)
}
tasks.withType<Test>().configureEach {
configure<JacocoTaskExtension> {
// Required for JaCoCo + Robolectric
// https://github.com/robolectric/robolectric/issues/2230
isIncludeNoLocationClasses = true
// Required for JDK 11 with the above
// https://github.com/gradle/gradle/issues/5184#issuecomment-391982009
excludes = listOf("jdk.internal.*")
}
}
}
我还创建了一个
AndroidApplicationJacocoConventionPlugin
和一个 AndroidLibraryJacocoConventionPlugin
。就像 NowInAndroid 一样。
当我在应用程序模块中运行 androidTest 时,它工作正常,创建了coverage.ec 文件,但是当我尝试在库模块中运行它时,它创建了coverage.ec 但文件是空的,有人可以帮助我吗是吗?
我只是不明白为什么它适用于应用程序模块,但不适用于其他模块。
我发现问题是androidTest生成的apk在我的项目中不可调试。添加:
(this as com.android.build.gradle.internal.dsl.BuildType).isDebuggable = true
对于库模块解决了这个问题。