I have an Android app which is made up of 2 modules:
App - UI
Submodule - has most of the business logic
For each of them I have a gradle task to validate code coverage:
App: UI Code coverage (Espresso)
Submodule: Unit tests code coverage
As a requirement for the client, I need to merge those two reports to get the overall/global code coverage of the app.
Note: I'm using Gradle version 3.1.2.
apply plugin: 'jacoco'
android {
   testBuildType "uiTest"
    ...
  buildTypes {
    debug {
        applicationIdSuffix ".debug"
        versionNameSuffix "-debug"
        debuggable true
        minifyEnabled false
        shrinkResources false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        matchingFallbacks = ['debug']
    }
    // TESTS
    // unitTest will be used to run unit tests.
    unitTest.initWith(buildTypes.debug) //Beware the buildType this depends on MUST be above on the gradle file
    unitTest {
        applicationIdSuffix ".unitTest"
        versionNameSuffix "-unitTest"
        testCoverageEnabled = true
        matchingFallbacks = ['unitTest', 'debug']
    }
    // uiTest will be used to run ui tests.
    uiTest.initWith(buildTypes.debug) //Beware the buildType this depends on MUST be above on the gradle file
    uiTest {
        applicationIdSuffix ".uiTest"
        versionNameSuffix "-uiTest"
        testCoverageEnabled = true
        matchingFallbacks = ['uiTest', 'debug']
    }
    ...
apply plugin: 'jacoco'
android {
   testBuildType "uiTest"
   buildTypes {
    debug {
    }
    unitTest {
        initWith(buildTypes.debug)
        testCoverageEnabled = true
    }
    uiTest {
        initWith(buildTypes.debug)
        testCoverageEnabled = true
    }
  ...
}
I've tried several ways, this one below indeed merges the tests.. but the coverage is not appearing correctly:
//UI Test Coverage filtered (we need to run unit tests of App to be able to use Jacoco to filter)
task createTestReport(type: JacocoReport, dependsOn: [':app:testUnitTestUnitTest', ':app:createUiTestAndroidTestCoverageReport']) {
reports {
    html.enabled = true
}
def fileFilter = [
        //Android stuff
        '**/R.class',
        '**/BR.class',
        '**/R$*.class',
        '**/BR$*.class',
        '**/BuildConfig.*',
        'android/**/*.*',
        //Data Binding
        '**/*databinding',
        '**/*binders',
        '**/*layouts',
        '**/Manifest*.*',
        '**/*Test*.*',
        "**/services/**/model/**",
        //Utils
        '**/utils/*.*',
        '**/utils/**/*.*'
]
//To support Java coverage on Unit tests
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/unitTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/unitTest", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
def debugSrc = "${project.projectDir}/src/debug/java"
sourceDirectories = files([mainSrc, debugSrc])
def appAndroidTests = fileTree(dir: "${buildDir}/outputs/code-coverage/connected/", includes: ["**/*.ec"])
def appOtherAndroidTests = fileTree(dir: "${buildDir}/outputs/androidTest-results/connected/", includes: ["**/*.ec"])
classDirectories = files([debugTree], [kotlinDebugTree])
executionData = files("${buildDir}/jacoco/testUnitTestUnitTest.exec", appAndroidTests, appOtherAndroidTests)
}
//Unit Test Coverage filtered
task createTestReport(type: JacocoReport, dependsOn: ['testUnitTestUnitTest']) {
reports {
    html.enabled = true
}
def fileFilter = ['**/R.class',
                  '**/BR.class',
                  '**/R$*.class',
                  '**/BR$*.class',
                  '**/BuildConfig.*',
                  '**/*databinding/**/*.*',
                  '**/Manifest*.*',
                  '**/*Test*.*',
                  "**/services/**/model/**",
                  'android/**/*.*',
                  '**/utils/*.*',
                  '**/utils/**/*.*']
//To support Java coverage on Unit tests
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/unitTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/unitTest", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
def debugSrc = "${project.projectDir}/src/debug/java"
sourceDirectories = files([mainSrc, debugSrc])
classDirectories = files([debugTree], [kotlinDebugTree])
executionData = files("${buildDir}/jacoco/testUnitTestUnitTest.exec")
}
//Global Test Coverage
task createGlobalTestReport(type: JacocoReport, dependsOn: [':app:testUnitTestUnitTest', ':app:createTestReport', ':submodule:testUnitTestUnitTest']) {
reports {
    html.enabled = true
}
def fileFilter = [
        //Android stuff
        '**/R.class',
        '**/BR.class',
        '**/R$*.class',
        '**/BR$*.class',
        '**/BuildConfig.*',
        'android/**/*.*',
        //Data Binding
        '**/*databinding',
        '**/*binders',
        '**/*layouts',
        '**/Manifest*.*',
        '**/*Test*.*',
        "**/services/**/model/**",
        //Utils
        '**/utils/*.*',
        '**/utils/**/*.*'
]
// Note: **/reviews/ReviewService*.* was added as BazaarVoice cannot be mocked
//To support Java coverage on Unit tests
def debugAppTree = fileTree(dir: "${buildDir}/intermediates/classes/unitTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def debugKotlinAppTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/unitTest", excludes: fileFilter)
def debugSdkTree = fileTree(dir: "..//build/intermediates/classes/unitTest", excludes: fileFilter)
def debugKotlinSdkTree = fileTree(dir: "../submodule/build/tmp/kotlin-classes/unitTest", excludes: fileFilter)
def mainAppSrc = "${project.projectDir}/src/main/java"
def debugAppSrc = "${project.projectDir}/src/debug/java"
def mainSdkSrc = "../submodule/src/main/java"
def debugSdkSrc = "../submodule/src/debug/java"
sourceDirectories = files([mainAppSrc, debugAppSrc,
                           mainSdkSrc, debugSdkSrc])
def appAndroidTests = fileTree(dir: "${buildDir}/outputs/code-coverage/connected/", includes: ["**/*.ec"])
def sdkAndroidTests = fileTree(dir: "../submodule/build/outputs/code-coverage/connected/", includes: ["**/*.ec"])
classDirectories = files([debugAppTree, debugSdkTree,
                          debugKotlinAppTree, debugKotlinSdkTree])
executionData = files("${buildDir}/jacoco/testUnitTestUnitTest.exec"
        , "../submodule/build/jacoco/testUnitTestUnitTest.exec"
        , appAndroidTests
        , sdkAndroidTests
)
}
Any help would be much appreciated
I'm not sure it works with multiple build types.
Try merging it into a single build type and:
apply plugin: 'jacoco'
android {
   testBuildType "automationTest"
    ...
  buildTypes {
    debug {
        applicationIdSuffix ".debug"
        versionNameSuffix "-debug"
        debuggable true
        minifyEnabled false
        shrinkResources false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        matchingFallbacks = ['debug']
    }
    // TESTS
    automationTest {
        applicationIdSuffix ".automationTest"
        versionNameSuffix "-automationTest"
        testCoverageEnabled = true
        matchingFallbacks = ['automationTest', 'debug']
    }
    ...
apply plugin: 'jacoco'
android {
   buildTypes {
    debug {
    }
    automationTest {
        initWith(buildTypes.debug)
        testCoverageEnabled = true
    }
    release {
        initWith(buildTypes.debug)
    }
  ...
}
task createUnitTestReport(type: JacocoReport, dependsOn: ['testAutomationTestUnitTest']) {
reports {
    html.enabled = true
}
def fileFilter = ['**/R.class',
                  '**/BR.class',
                  '**/R$*.class',
                  '**/BR$*.class',
                  '**/BuildConfig.*',
                  '**/*databinding/**/*.*',
                  '**/Manifest*.*',
                  '**/*Test*.*',
                  'android/**/*.*']
//To support Java coverage on Unit tests
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/automationTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/automationTest", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
def debugSrc = "${project.projectDir}/src/debug/java"
sourceDirectories = files([mainSrc, debugSrc])
classDirectories = files([debugTree], [kotlinDebugTree])
executionData = files("${buildDir}/jacoco/testAutomationTestUnitTest.exec")
}
task createGlobalTestReport(type: JacocoReport,
    dependsOn: [':app:createUiTestReport', ':submodule:createUnitTestReport']) {
reports {
    html.enabled = true
}
def fileFilter = [
        //Android stuff
        '**/R.class',
        '**/BR.class',
        '**/R$*.class',
        '**/BR$*.class',
        '**/BuildConfig.*',
        'android/**/*.*',
        //Data Binding
        '**/*databinding',
        '**/*binders',
        '**/*layouts',
        '**/Manifest*.*',
        '**/*Test*.*'
]
//To support Java coverage on Unit tests
def debugAppTree = fileTree(dir: "${buildDir}/intermediates/classes/automationTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def debugKotlinAppTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/automationTest", excludes: fileFilter)
def debugSdkTree = fileTree(dir: "../submodule/build/intermediates/classes/automationTest", excludes: fileFilter)
def debugKotlinSdkTree = fileTree(dir: "../submodule/build/tmp/kotlin-classes/automationTest", excludes: fileFilter)
def mainAppSrc = "${project.projectDir}/src/main/java"
def debugAppSrc = "${project.projectDir}/src/debug/java"
def mainSdkSrc = "../submodule/src/main/java"
def debugSdkSrc = "../submodule/src/debug/java"
sourceDirectories = files([mainAppSrc, debugAppSrc,
                           mainSdkSrc, debugSdkSrc])
classDirectories = files([debugAppTree, debugSdkTree,
                          debugKotlinAppTree, debugKotlinSdkTree])
def appAndroidTests = fileTree(dir: "${buildDir}/outputs/code-coverage/connected/", includes: ["*.ec"])
executionData = files("${buildDir}/jacoco/testAutomationTestUnitTest.exec"
        , "../submodule/build/jacoco/testAutomationTestUnitTest.exec"
        , appAndroidTests
)
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With