使用 Jacoco 测量多模块和动态功能模块 Android 项目中的测试覆盖率

Measuring tests coverage in multi-module and dynamic feature module Android project using Jacoco

我目前正在开发一个新的 Android 应用程序,我试图在其中使用模块化原则。

我的 android 项目由以下模块组成:

我想为 CI (Azure Pipeline) 生成一个统一的代码覆盖率报告,我可以在其中看到所有模块的单元测试和仪器测试的全局代码覆盖率。

我阅读了很多文章并尝试了几个自定义 jacoco gradle 插件来生成这样的报告但没有成功。

我终于写了下面的jacoco.gradle文件:

apply plugin: 'jacoco'

tasks.withType(Test) {
  jacoco.includeNoLocationClasses = true
  jacoco.excludes = ['jdk.internal.*']
}

project.afterEvaluate {
}
tasks.create(name: "createUnifiedCoverageReport", type: JacocoReport, dependsOn: [
':app:testInternalDebugUnitTest', ':app:createInternalDebugCoverageReport',
':home:testInternalDebugUnitTest', ':home:createInternalDebugCoverageReport',
':core:testDebugUnitTest', ':core:createDebugCoverageReport',
]) {

  reports
  {
    html.enabled = true
    xml.enabled = true
    csv.enabled = false
  }

  def fileFilter = [ 
    //some files to filter
  ]

  classDirectories.setFrom(files([
  //app
  fileTree(dir: "$project.rootDir/app/build/tmp/kotlin-classes/internalDebug", excludes: fileFilter),
  fileTree(dir: "$project.rootDir/app/build/intermediates/javac/internalDebug", excludes: fileFilter),

  //home
  fileTree(dir: "$project.rootDir/home/build/tmp/kotlin-classes/debug", excludes: fileFilter),
  fileTree(dir: "$project.rootDir/home/build/intermediates/javac/debug", excludes: fileFilter),

  //core
  fileTree(dir: "$project.rootDir/core/build/tmp/kotlin-classes/debug", excludes: fileFilter),
  fileTree(dir: "$project.rootDir/core/build/intermediates/javac/debug", excludes: fileFilter),
  ]))

  def coverageSourceDirs = [
  //app
  "$project.rootDir/app/src/main/java",
  "$project.rootDir/app/src/main/kotlin",

  //home
  "$project.rootDir/home/src/main/java",
  "$project.rootDir/home/src/main/kotlin",

  //core
  "$project.rootDir/core/src/main/java",
  "$project.rootDir/core/src/main/kotlin",
  ]

  additionalSourceDirs.setFrom(files(coverageSourceDirs))
  sourceDirectories.setFrom(files(coverageSourceDirs))

  def uiAppTestsData = fileTree(dir: "${project.rootDir}/app/build/outputs/code_coverage/internalDebugAndroidTest/connected/", includes: ["**/*.ec"])
  def uiHomeTestsData = fileTree(dir: "${project.rootDir}/home/build/outputs/code_coverage/internalDebugAndroidTest/connected/", includes: ["**/*.ec"])
  def uiCoreTestsData = fileTree(dir: "${project.rootDir}/core/build/outputs/code_coverage/debugAndroidTest/connected/", includes: ["**/*.ec"])

  executionData(files([
  //app
  uiAppTestsData,
  "$project.rootDir/app/build/jacoco/testInternalDebugUnitTest.exec",

  //home
  uiHomeTestsData,
  "$project.rootDir/home/build/jacoco/testInternalDebugUnitTest.exec",

  //core
  uiCoreTestsData,
  "$project.rootDir/core/build/jacoco/testDebugUnitTest.exec",
  ]))
}

jacoco.gradle 然后通过以下指令应用于每个模块:

apply from: '../jacoco.gradle'

因此,为了创建统一的代码覆盖率报告,我使用 gradle 任务 createUnifiedCoverageReport

该任务创建一个统一的代码覆盖率报告,其中包含 appcore 模块的类。但是此报告中缺少 home 模块中的 类。

所以我有几个问题:

感谢您的帮助。

配置正常,但模块的 类 路径不正确。风味信息丢失:

fileTree(dir: "$project.rootDir/home/build/tmp/kotlin-classes/internalDebug", excludes: fileFilter),
fileTree(dir: "$project.rootDir/home/build/intermediates/javac/internalDebug", excludes: fileFilter),