JaCoCo在Kotlin和Android 3.0中返回0%的覆盖率

39

我正在尝试检查我用Kotlin编写的测试用例的代码覆盖率。当我执行./gradlew createDebugCoverageReport --info时,我的coverage.ec文件为空,并且我的报告显示我的覆盖率为0%。请注意,这些测试用例100%成功。有人能想到为什么我的coverage.ec文件一直返回0字节吗?

我已经到处搜索了,但没有找到答案。

apply plugin: 'com.android.library'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

apply plugin: 'jacoco'


android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        debug {
            testCoverageEnabled = true
        }
        release {
            minifyEnabled false
            testCoverageEnabled = true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }


    testOptions {
        unitTests.all {
            jacoco {
                includeNoLocationClasses = true
            }
        }
    }

}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:25.4.0'
    testImplementation 'junit:junit:4.12'
    implementation files('pathtosomejarfile')

}



jacoco {
    toolVersion = "0.7.6.201602180812"
    reportsDir = file("$buildDir/customJacocoReportDir")

}



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/androidTest/java"

    sourceDirectories = files([mainSrc])
    classDirectories = files([debugTree])
    executionData = fileTree(dir: "$buildDir", includes: [
            "jacoco/testDebugUnitTest.exec",
            "outputs/code-coverage/connected/*coverage.ec"
    ])
}

https://dev59.com/z6Pia4cB1Zd3GeqP4NC8 - Entreco
不仅是Jacoco,甚至Intellij IDEA的默认覆盖率也为0。当使用Kotlin时,所有东西都为0。https://dev59.com/dlcO5IYBdhLWcg3wbBE8 - Elye
3个回答

29

你可以通过定义两个不同的目录来获得Java和Kotlin代码逐行覆盖率的覆盖信息,这些目录是生成的.class文件所在的位置:

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

那么,只需将两个fileTree包含在classDirectories中即可:

classDirectories.from = files([debugTree], [kotlinDebugTree])

这是根据stackoverflow.com/a/45354933/3286489报告的。但是如果仔细观察,它报告的是测试代码的覆盖率,而不是应用程序代码。 :( - Elye
4
建议的解决方案应该有效。我当时不知道这篇文章,但以类似的方式进行了修复。我写了一篇关于这个的博客文章:http://vgaidarji.me/blog/2017/12/20/how-to-configure-jacoco-for-kotlin-and-java-project/ - Veaceslav Gaidarji
感谢@VeaceslavGaidarji! - Clinkz
classDirectories已被弃用。那么答案应该是什么? - charitha amarasinghe
1
请使用classDirectories.from而不是classDirectories - farmerbb
最好有人能指导我在哪里使用这段代码。 - jknair0

0
几天后,我找到了解决这个问题的方法。对于那些遇到类似问题的人: 在您的 intermediates 文件夹中应该有一个 tmp 文件夹。此文件夹包含 Kotlin 文件的 .class 文件。如果您将 fileTree(dir: "${buildDir}/intermediates/classes/debug", excludes: fileFilter) 的路径更改为这些 class 文件所在的位置,则 Jacoco 将为您生成代码覆盖率!请注意,使用此方法,您将无法看到完整的逐行覆盖范围概述。

但为什么?它不能使用 -> {buildDir}/tmp/kotlin-classes/universalDebugAndroidTest/ 路径吗? - Astha Garg

0

尝试使用与JaCoCo和IntelliJ兼容的新kotlinx-kover Gradle插件。
它解决了报告为0%inline函数的问题,可能还有其他问题。

plugins {
     id("org.jetbrains.kotlinx.kover") version "0.5.0"
}

一旦应用了插件,就可以直接使用,无需额外配置。
观看 YouTube announcement video 并跟踪 this youtrack issue 的路线图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接