androidgradlejacoco-plugin

JacocoReport Task: Get overall coverage by simply adding submodules files to sourceDirectories and classDirectories?


Tool Version

gradle 5.6.4

java 1.8

jacoco toolVersion 0.8.2

Project Structure

├── build.gradle
├── app
│   ├── build.gradle (1)
│   └── src
├── submodule_1
│   ├── build.gradle (2)
│   └── src
├── submodule_2
│   ├── build.gradle (3)
│   └── src
├── gradle
│   ├── jacoco.gradle
│   └── other_scripts.gradle

Description

(1) imports jacoco.gradle.

(1), (2) and (3) have the following configuration:

    buildTypes {
        debug {
            testCoverageEnabled true
        }
    }

Problem

I want to get an overall coverage, can I just simply include the files of submodules in the properties classDirectories and sourceDirectories, or shell I include them in additionalClassDirs? I don't really understand their difference.

Here is gradle/jacoco.gradle imported by app/build.gradle.

apply plugin: 'jacoco'

def coverageSourceDirs = [
        "${rootDir.absolutePath}/app/src",
        "${rootDir.absolutePath}/submodule_1/src",
        "${rootDir.absolutePath}/submodule_2/src",
]

def coverageClassDirs = [
        fileTree(dir: "${rootDir.absolutePath}/app/build/intermediates/javac/SNMAPP__10009Debug/compileSNMAPP__10009DebugJavaWithJavac/classes", excludes: androidExclusion),
        fileTree(dir: "${rootDir.absolutePath}/submodule_1/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes", excludes: androidExclusion),
        fileTree(dir: "${rootDir.absolutePath}/submodule_2/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes", excludes: androidExclusion),
]

task jacocoTestReport_test(type: JacocoReport) {
    group = "Reporting"
    description = "Generate Jacoco coverage reports runing tests."

    reports {
        xml.enabled = true
        html.enabled = true
        html.destination file("${rootDir.absolutePath}/app/build/reports/jacoco")
    }
    sourceDirectories = files(coverageSourceDirs)
    classDirectories = files(coverageClassDirs)
    executionData = files("${rootDir.absolutePath}/app/build/outputs/code_coverage/SNMAPP__10009DebugAndroidTest/connected/coverage.exec")
}

Solution

  • Yes, you just need to include the files of submodules in classDirectories and sourceDirectories. By the way, you should include all of test result of your submodules in executionData

    def appAndroidTests = fileTree(dir: "${buildDir}/outputs/code_coverage/{your flavor}AndroidTest/connected", includes: ["*.ec"])
    
    executionData = files(
      "${buildDir}/jacoco/test{your flavor}UnitTest.exec",
      "../submodule_1/build/jacoco/test{your flavor}UnitTest.exec",
      "../submodule_2/build/jacoco/test{your flavor}UnitTest.exec",
      appAndroidTests
    )