android - Jacoco 和 android-gradle-plugin >= 1.1 的单元测试代码覆盖率

标签 android unit-testing android-gradle-plugin jacoco

我最近开始在我的一个项目中集成 android-gradle-plugin 1.1.0。该项目使用 robolectric 2.4 来运行单元测试。

这是一个多模块项目,具有非常复杂的依赖关系(一些模块依赖于其他模块)。类似的东西:

--> application-module (dependsOn: module1, module2, module-core)
    --> module1 (dependsOn: module-core)
    --> module2 (dependsOn: module-core)
    --> module-core (dependsOn: module3, module4)
        --> module3 (library dependencies)
        --> module4 (library dependencies)

如需更清晰的图片,请参阅 jacoco-example项目。

我试图集成 JaCoCo 来为单元测试生成报告,但在我看来它只运行 androidTests 基本上是仪器测试。

经过一些谷歌搜索后,我在 GitHub 和其他文章上遇到了一些项目,但它们主要集中在以前版本的 android-gradle-plugin 或正在使用其他第三方android-unit-test 等插件 for example here .

可能是我失去了使用谷歌搜索的能力。但是有人可以指出我可以找到一些关于 android gradle 插件中的新内容以及如何仅针对单元测试运行 jacoco 任务的文档的方向吗?

更新

采用 nenick's example 的脚本:

apply plugin: "jacoco"

configurations {
    jacocoReport
}

task jacocoReport(dependsOn: 'testDebug') << {
    ant {
        taskdef(name:'jacocoreport',
                classname: 'org.jacoco.ant.ReportTask',
                classpath: configurations.jacocoReport.asPath)

        mkdir dir: "${buildDir}/test-coverage-report"
        mkdir dir: "${buildDir}/reports/jacoco/test/"

        jacocoreport {
            executiondata = files("${buildDir}/jacoco/testDebug.exec")

            structure(name: "${rootProject.name}") {
                classfiles {
                    fileset (dir: "${buildDir}/intermediates/classes/debug") {
                        //exclude(name: '**/*_*.class')
                        exclude(name: '**/R.class')
                        exclude(name: '**/R$*.class')
                        exclude(name: '**/BuildConfig.class')
                    }
                }

                sourcefiles {
                    fileset dir: "src/main/java"
                    fileset dir: "${buildDir}/generated/source/buildConfig/debug"
                    fileset dir: "${buildDir}/generated/source/r/debug"
                }
            }

            xml destfile: "${buildDir}/reports/jacoco/test/jacocoTestReport.xml"
            html destdir: "${buildDir}/test-coverage-report/"
        }
    }
}

dependencies {
    jacocoReport 'org.jacoco:org.jacoco.ant:0.7.2.201409121644'
}

之后,./gradlew jacocoReport 执行并生成报告,但它显示 0(零)测试覆盖率,这是不可能的,因为至少有一半的类都经过测试。

UPDATE_2

试用了example .将下一个任务添加到我的一个 gradle 构建文件中:

task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
    group = "Reporting"
    description = "Generate Jacoco coverage reports"

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

    sourceDirectories = files("${buildDir.parent}/src/main/java")
    additionalSourceDirs = files([
            "${buildDir}/generated/source/buildConfig/debug",
            "${buildDir}/generated/source/r/debug"
    ])
    executionData = files("${buildDir}/jacoco/testDebug.exec")

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

同样的问题,生成了报告,但代码覆盖率仍然为零。

UPDATE_3

UPDATE_2 中的任务似乎有效,但仅适用于带有 apply plugin: 'com.android.application' 的模块(报告正确生成)。但是对于 android 库模块(apply plugin: 'com.android.library'),报告显示零覆盖率,尽管模块包含的测试比应用程序模块多。

UPDATE_4

创建了一个简单的示例项目来演示我的问题。目前,如果您运行 ./gradlew jacocoReport 会生成报告,但不会显示模块项目的测试覆盖率。看到这个link

简短说明:当测试是 AndroidUnitTests(白化 JUnit 4 和 Robolectric)时,JaCoCo 报告显示了所有模块的覆盖范围。

有什么想法吗?

最佳答案

经过一番折腾,我决定创建一个 open source Gradle plugin为此。

根 build.gradle

buildscript {
    repositories {
        mavenCentral() // optional if you have this one already
    }
    dependencies {
        classpath 'com.vanniktech:gradle-android-junit-jacoco-plugin:0.16.0'
    }
}

apply plugin: 'com.vanniktech.android.junit.jacoco'

然后直接执行

./gradlew jacocoTestReportDebug

它将在 Debug模式下运行 JUnit 测试,然后在相应的构建目录中以 XML 和 HTML 形式为您提供 Jacoco 输出。

它还支持 flavor 。将创建红色和蓝色 2 种口味的任务

  • jacocoTestReportRedDebug
  • jacocoTestReportBlueDebug
  • jacocoTestReportRedRelease
  • jacocoTestReportBlueRelease

关于android - Jacoco 和 android-gradle-plugin >= 1.1 的单元测试代码覆盖率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28586882/

相关文章:

android - 为亚马逊构建一个未签名的 apk,为谷歌构建一个签名的 apk

android - 如何将 Google Play 服务更新到 9.8.7 以在 Google Pixel 上运行

java - 通过引用多个 Spinner 的 setOnItemSelectedListener 来传递 String 变量

android - Runtime.exec() 错误 : hangs without providing a Process object

java - 如何使用 Spring 在单元测试中模拟远程 REST API?

perl - 如何为同一发行版中的多个 Perl 模块设计单元测试?

android - 程序类型已存在 : android. support.v4.media.MediaBrowserCompat$CustomActionCallback

android - 如何在android中的谷歌地图上绘制两点以上的路线?

java - 如何将对象 ArrayList 中的文本设置到 TextView 中?

python - python google-app-engine 网站的代码覆盖率?