Search code examples
androidandroid-gradle-pluginbuild.gradlejacococodecov

Android CodeCov/Jacoco for Library Module


I am trying to implement CodeCov/Jacoco as described here:

https://about.codecov.io/blog/code-coverage-for-android-development-using-kotlin-jacoco-github-actions-and-codecov/

This guide works really well for the main app module, specified with 'com.android.application in the app-level build.gradle.

However, I have a second library module called video_library that is specified as a library with 'com.android.library' on its build.gradle.

Whenever I try and run the Jacoco tasks for the video_library module, the tasks run but it fails to run any of the unit tests I have written, as if it cannot find any tests (although there are over 50 for this module)

enter image description here

The project structure is as follows:

├── app
│   ├── build
│   └── src
├── build
│   └── kotlin
├── gradle
│   └── wrapper
└── library_video
    ├── build
    ├── sampledata
    └── src

I have implemented the jacocoTestReport in the same way as the app module:

plugins {
        id 'com.android.library'
        id 'kotlin-android'
        id 'kotlin-kapt'
        id 'org.jetbrains.dokka'
        id 'maven-publish'
        id 'jacoco'
    }
    
    task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) {
    
        reports {
            xml.enabled = true
            html.enabled = true
        }
    
        def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
        def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/debug", excludes: fileFilter)
        def mainSrc = "${project.projectDir}/src/main/java"
    
        sourceDirectories.setFrom(files([mainSrc]))
        classDirectories.setFrom(files([debugTree]))
        executionData.setFrom(fileTree(dir: "$buildDir", includes: [
                "jacoco/testDebugUnitTest.exec",
                "outputs/code-coverage/connected/*coverage.ec"
        ]))
    }

Are there adjustments that I need to make for the library_video module implementation to find the tests?


Solution

  • You need to include to classDirectories library_video classes manually in :app module. This is at least what help me to achieve multi-module code coverage.

    In the :app module (I am using Gradle KTS, hence in Kotlin):

    val library_video_dir = fileTree(mapOf("dir" to "${buildDir}/../../library_video/build/classes/kotlin/main", "excludes" to fileFilter))
    
    classDirectories.setFrom(files(listOf(debugTree, library_video_dir)))
    

    Try experimenting with dir path as it is different for Java