Jacoco informa 0 cobertura de classs de Kotlin por testings unitarias, en un proyecto de Android

Estoy usando Android Gradle Plugin 3.0.0.

Estoy migrando una aplicación de Android de Java a Kotlin. Mi aplicación tiene classs en Java y Kotlin, y las testings están en Java.

./gradlew clean jacocoTestReport .

Esto ejecuta tanto testings unitarias ( src/test ) como testings de instrumentación ( src/androidTest ).

El informe producido por jacoco en app/build/reports/jacoco/jacocoTestReport/html/index.html no muestra la cobertura de las classs de Kotlin que sí están cubiertas por testings unitarias.

El informe muestra la cobertura correctamente de las testings de instrumentación.

Nota: me encontré con estas otras preguntas, que no son exactamente el mismo problema:

  • JaCoCo que devuelve 0% de Cobertura con Kotlin y Android 3.0 tiene un problema con la cobertura del código mediante testings de instrumentación, no testings unitarias.
  • Informes de Android Studio JaCoCo 0% de cobertura tiene un problema con la cobertura del código desde dentro de Android Studio, pero no es específico de Kotlin.

Partes relevantes de build.gradle de mi module de aplicación:

 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" ]) } 

Tuve que agregar includeNoLocationClasses = true a mi file gradle de la siguiente manera, para hacer que el informe de jacoco refleje la cobertura de las classs de Kotlin por testings unitarias:

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

Nota: esta solución funciona para ejecutar testings desde la command-line, pero aún obtengo una cobertura del 0% cuando se ejecuta con cobertura desde dentro de Android Studio.

  • A la class le falta un constructor sin arguments, pero he proporcionado un constructor sin arguments
  • Lea la línea y agregue algo al final
  • Clase de datos KotlinReflectionInternalError
  • ¿Cómo crear una implementación de interfaz anónima en mi class de Kotlin y usarla?
  • Error de compilation de Kotlin: no se puede invocar ninguna de las siguientes funciones con los arguments suministrados
  • ¿Cómo se organizan múltiples corrutines y bloques de expectativas en una testing de Kotlin Spek?
  • En kotlin, cómo devolver una instancia definida por un parámetro de class genérico
  • Diferencia entre typealias y val para el object
  • Kotlin null de Java
  • Cambia la orientación del menu de fab programáticamente
  • Kotlin: ¿Necesita proteger la class de datos de Kotlin?