rolandl
rolandl

Reputation: 1887

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

I am currently developping a new Android application in which one I am trying to use the modularization principles.

My android project is composed of the folllowing modules:

I would like to produce an unified code coverage report for the CI (Azure Pipeline) in which one I can see the global code coverage of unit tests and instrumented tests for all the modules.

I read so many articles and tried several custom jacoco gradle plugins in order to produce a such report with no success.

I finally wrote the following jacoco.gradle file:

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",
  ]))
}

This jacoco.gradle is then applied in each module with the following instruction:

apply from: '../jacoco.gradle'

So, in order to create the unified code coverage report, I use the gradle task createUnifiedCoverageReport.

The task create an unified code coverage report that contains the classe of the app and the core modules. But the classes from the home module is missing from this report.

So I have several questions:

Thank you for your help.

Upvotes: 2

Views: 1212

Answers (1)

rolandl
rolandl

Reputation: 1887

The configuration was OK but the path of the classes for the module was incorrect. The flavor information was missing :

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

Upvotes: 1

Related Questions