简体   繁体   中英

Jacoco is reporting 0 coverage of Kotlin classes by unit tests, in an Android project

I'm using Android Gradle Plugin 3.0.0.

I'm migrating an Android app from java to kotlin. My app has classes in Java and Kotlin, and tests are in Java.

I run ./gradlew clean jacocoTestReport .

This runs both unit tests ( src/test ) and instrumentation tests ( src/androidTest ).

The report produced by jacoco in app/build/reports/jacoco/jacocoTestReport/html/index.html doesn't show coverage for Kotlin classes which are indeed covered by unit tests.

The report does show coverage correctly from instrumentation tests.

Note: I came across these other questions, which aren't exactly the same issue:

Relevant portions of my app module's build.gradle:

apply plugin: 'jacoco'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
...
android {
    defaultConfig {
        sourceSets {
            main.java.srcDirs += "$projectDir/src/main/kotlin"
        }
    }

    testOptions {
        unitTests {
            all {
                jvmArgs '-noverify', '-ea'
            }
            includeAndroidResources = true
        }
    }
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    ....
}

jacoco {
    toolVersion '0.7.9'
}

task jacocoTestReport(type: JacocoReport, dependsOn: ["testDebugUnitTest", "createDebugCoverageReport"]) {
    reports {
        html.enabled = true
    }
    classDirectories = fileTree(
            dir: "${buildDir}",
            includes: ["tmp/kotlin-classes/debug/ca/rmen/android/poetassistant/**/*.class",
                       "intermediates/classes/debug/ca/rmen/android/poetassistant/**/*.class"],
            excludes: ["**/R.class", "**/R*.class", "**/Manifest.class", "**/Manifest*.class", "**/BuildConfig.class",
                       // ignore databinding generated code:
                       "**/ca/rmen/android/poetassistant/databinding/*.class",
                       ... other excludes ...
                       "**/ca/rmen/android/poetassistant/BR.class",
                       "**/com/android/**/*.class"])
    sourceDirectories = files("${project.projectDir}/src/main/java", "${project.projectDir}/src/main/kotlin")
    executionData = fileTree(
            dir: "${buildDir}",
            includes: [
                    "jacoco/testDebugUnitTest.exec",
                    "outputs/code-coverage/connected/*coverage.ec"
            ])
}

I had to add includeNoLocationClasses = true to my gradle file as follows, to make the jacoco report reflect the coverage of Kotlin classes by unit tests:

android {
    testOptions {
        unitTests {
            all {
                jvmArgs '-noverify', '-ea'
                jacoco {
                    includeNoLocationClasses = true
                }
            }
            includeAndroidResources = true
        }
    }
}

Note: this solution works for running tests from the command line, but I still get 0% coverage when running with coverage from inside Android Studio.

Add below line in jacoco.gradle file for getting the kotlin classes

            def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug", excludes: fileFilter)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM