Android - Jacoco代码覆盖率忽略Robolectric测试

8

我试图在Android中利用Jacoco实现对Robolectric测试代码的覆盖率检测,但是在生成报告时它却无法识别我的Robolectric测试代码。

我的jacoco.gradle文件如下:

apply plugin: 'jacoco'

jacoco {
    toolVersion = "0.7.6.201602180812"
}

project.afterEvaluate {

    android.applicationVariants.all { variant ->
        def name = variant.name
        def testTaskName = "test${name.capitalize()}UnitTest"

        tasks.create(name: "${testTaskName}Coverage", type: JacocoReport, dependsOn: "$testTaskName") {
            group = "Reporting"
            description = "Generate Jacoco coverage reports for the ${name.capitalize()} build."

            classDirectories = fileTree(
                    dir: "${project.buildDir}/intermediates/classes/${name}",
                    excludes: ['**/R.class',
                               '**/R$*.class',
                               '**/*$ViewInjector*.*',
                               '**/*$ViewBinder*.*',
                               '**/BuildConfig.*',
                               '**/Manifest*.*']
            )

            sourceDirectories = files(['src/main/java'].plus(android.sourceSets[name].java.srcDirs))
            executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")

            reports {
                xml.enabled = true
                html.enabled = true
            }
        }
    }
}

通过这种设置,我可以获得覆盖率报告,但尽管在“src/test/java”中有Robolectric测试,但我得到了0%的覆盖率。

如果我将以下代码添加到该文件中:

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

当Gradle尝试同步时,我会收到以下错误:

错误:对于类org.gradle.testing.jacoco.plugins.JacocoTaskExtension_Decorated,不存在includeNoLocationClasses属性。

我知道我需要使用includeNoLocationClasses值的Gradle版本为2.13。因此在graddle-wrapper.properties文件中,我添加了以下内容:

#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-2.13-20160228000026+0000-all.zip

我非常确定我正在使用Gradle 2.13和Android插件版本1.5。

在我的应用程序的Gradle文件中,我有以下内容:

//...

apply from: 'jacoco.gradle'

//..

testOptions {
    unitTests.returnDefaultValues = true
}

//...

debug {
    testCoverageEnabled true
}

我用来运行覆盖率的命令是:

./gradlew createDebugCoverageReport

所以我想知道为什么我使用正确的Gradle版本仍然会出现includeNoLocationClasses错误?除此之外,也许我做错了什么,导致Jacoco没有捕捉到src/test.java中的Robolectric测试?


我注意到这段代码现在已经过时了(在gradle-android-plugin 3.x中):android { testOptions { unitTests.all { jacoco { includeNoLocationClasses = true } } } } - Alix
唐纳,能帮我一下吗?当我尝试执行你提到的配置时,我遇到了一个错误:“Error:Could not get unknown property 'android' for root project 'MyProject' of type org.gradle.api.Project.” 你有什么想法吗? - CoDe
抱歉 @CoDe,我记不起来了,而且我为此工作的代码已经被搁置了。如果我能回忆起来,我会告诉你的。 - Donal Rafferty
1个回答

8

我并没有完整地看到你的 build.gradle 文件,但是要添加这个标志,你需要:

  1. 使用 gradle 版本 2.13+
  2. 使用 jacoco 版本 0.7.6.201602180812

确定你正在使用正确版本的 gradle。因此,我认为问题仅在于使用了错误的 jacoco 版本。

提及 jacoco {toolVersion = "0.7.6.201602180812"} 不会影响 gradle DSL。你应该添加更新的 jacoco 插件:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'org.jacoco:org.jacoco.core:...'
    }
}

而且你应该应用插件,这一点你已经做到了:

apply from: 'jacoco'

在进行这样的配置后,您将不再需要 jacoco {toolVersion = "..."}
注意:考虑升级到更新的 Android Gradle 插件,2.2.x 已经稳定。同时,jacoco 也有新版本 0.7.7.201606060606
还有一点需要注意:如果您在 Android Studio 中看到原始问题,请检查您是否默认使用了包装器,并检查您是否将其指向了 gradle 2.13。

你能用 --debug--info 运行它吗?如果找不到可执行文件,它可能会跳过。因此,请仔细检查您的路径。 - Eugen Martynov
你可以运行 ./gradlew tasks 命令,查看你有哪些任务。此外,你在问题中调用了 createDebugCoverageReport,但是你的覆盖率任务命名为 test${variantname}Coverage - Eugen Martynov
1
这真是令人尴尬!我把两个教程混在一起,完全专注于使用一个教程推荐的createDebugCoverageReport,忘记了我正在创建变体任务,现在它可以工作了,非常感谢你的帮助。 - Donal Rafferty
apply from: 'jacoco.gradle' doesn't work. Needs to be: apply from: 'jacoco' - Alix
检查问题。他将所有的Jacoco Gradle代码提取到jacoco.gradle中。 - Eugen Martynov
显示剩余2条评论

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