Issue
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:
- JaCoCo returning 0% Coverage with Kotlin and Android 3.0 has a problem with code coverage by instrumentation tests, not unit tests.
- Android Studio JaCoCo reports 0% coverage has a problem with code coverage from inside Android Studio, but not Kotlin-specific.
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"
])
}
Solution
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.
Answered By - Carmen
Answer Checked By - David Goodson (JavaFixing Volunteer)