【问题标题】:Jacoco Code Coverage in android studioandroid studio 中的 Jacoco 代码覆盖率
【发布时间】:2015-05-21 22:16:29
【问题描述】:

我正在尝试生成 Jacoco 代码覆盖率报告。 我已将 AndroidTestCase 用于我的测试类。

我发现使用 testCoverageEnabled true 并使用默认 android -studio 默认 jacoco, ./gradlew connectedCheck 或 createDebugCoverageReport 创建成功/失败测试用例的百分比,但没有覆盖率报告。

然后我尝试了 jacoco {toolVersion "0.7.1.201405082137"} 和任务 jacocoTestReport(type:JacocoReport, dependsOn: "testDebug")。我试图通过各种任务更改dependsOn 值。该报告显示 0(零)测试覆盖率,这是不可能的,因为所有类中至少有一半经过测试。

在过去的几天里,我遵循了各种公认的堆栈溢出答案。结果是否定的。

我的 gradle 文件:

buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.0.0'        
    }
}

apply plugin: 'com.android.application'
apply plugin: 'jacoco'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "test.gradle.com.myapplicationtestgradle"
        minSdkVersion 21
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }

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

    jacoco {
        version "0.7.1.201405082137"
    }

    packagingOptions {
        exclude 'LICENSE.txt'
    }
}


jacoco {
    toolVersion "0.7.1.201405082137"
}

task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
    group = "Reporting"

    description = "Generate Jacoco coverage reports"

   // exclude auto-generated classes and tests
    def fileFilter = ['**/R.class', '**/R$*.class', 
    '**/BuildConfig.*', '**/Manifest*.*',           
     'android/**/*.*']
    def debugTree = fileTree(dir:   
    "${project.buildDir}/intermediates/classes/debug", 
    excludes: fileFilter)
    def mainSrc = "${project.projectDir}/src/main/java"

    sourceDirectories = files([mainSrc])
    classDirectories = files([debugTree])
    additionalSourceDirs = files([
            "${buildDir}/generated/source/buildConfig/debug",
            "${buildDir}/generated/source/r/debug"
    ])
    executionData = fileTree(dir: project.projectDir, includes: 
                    ['**/*.exec', '**/*.ec'])

    reports {
        xml.enabled = true
        xml.destination = "${buildDir}/jacocoTestReport.xml"
        csv.enabled = false
        html.enabled = true
        html.destination = "${buildDir}/reports/jacoco"
    }
}


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('junit:junit:4.11') {
        exclude module: 'hamcrest-core'
    }
}

【问题讨论】:

    标签: android android-studio jacoco test-coverage


    【解决方案1】:

    Gradle 已经内置支持生成测试覆盖率报告,我们不需要创建任何额外的配置或添加任何插件来生成测试覆盖率报告。基本上,我们唯一需要做的就是在build.gradle文件中将testCoverageEnabled参数设置为true,如下所示:

    android {
       buildTypes {
          debug {
             testCoverageEnabled = true
          }
       }
    }
    

    接下来,我们可以从 CLI 执行以下 Gradle 任务:

    ./gradlew createDebugCoverageReport
    

    在 Windows 上,我们可以这样执行:

    gradlew.bat createDebugCoverageReport
    

    Task 将分析我们项目在/src/main/java/ 目录中的代码和放在/src/androidTest/java/ 目录中的单元测试。 执行此任务后,我们可以在模块的以下目录中找到测试覆盖率报告:

    /build/outputs/reports/coverage/debug/
    

    当我们打开index.html文件时,我们可以看到测试覆盖率的可视化报告,可以在网络浏览器中查看。

    如下图所示。

    我写了一篇关于 Android 应用程序中的测试覆盖率报告的文章,并在前段时间发表在我的博客上。如果您对该主题感兴趣,可以阅读:

    更新(Robolectric 测试的单元测试覆盖率)

    如果您想从使用 Robolectric 编写的单元测试创​​建测试覆盖率报告,并使用 JacocoTravis CICodecov.io,请看我博客上的新文章:

    【讨论】:

    • 我看到的唯一问题是 /src/androidTest/java 在 Android Studio 上使用 JUnit 时不是默认设置。 /src/test/java 是目录。任何线索如何覆盖该目录?
    • 就我而言,我在/src/androidTest/java 中进行了所有测试,并且仍然正确生成了测试覆盖率报告。当您将所有测试放到 /src/test/java 或将部分测试(纯 java)放到一个目录而将另一部分(android)放到不同的目录时,我还没有检查它是如何工作的。
    • 但是我们要了解android studio本身是使用jacoco来生成测试报告的。
    • 好像用Android studio 2.0坏了,gradle plugin 2.0.0,你试过了吗?
    • 我没试过。据我所知,Android Studio 2.0 尚未正式发布,并且是预览版,因此可能存在错误。此外,您应该能够在没有 Android Studio 的情况下从命令行运行它。您只需要项目源代码、Gradle Wrapper 和 Gradle 配置即可。
    【解决方案2】:

    我看到您已经开始使用它了,但是,还有一种更简单的方法可以获取单元测试执行数据。我最近也在研究这个,实际上我写了一篇完整的文章earlier today

    在我的情况下,我不想创建额外的 Gradle 任务,因为我希望生成报告作为现有工作流程的一部分。我也不想显式添加 Jacoco 插件,因为 Google already dups Jacoco Ant 任务用于仪器测试的覆盖率报告。

    除了设置属性android.jacoco.versionbuildTypes.debug.testCoverageEnabled之外,我还在testDebug JVM参数中添加了以下内容以生成执行数据:

    project.afterEvaluate {
      def append = "append=true"
      def destFile = "destfile=$buildDir/outputs/code-coverage/connected/coverage.ec"
      testDebug.jvmArgs "-javaagent:$buildDir/intermediates/jacoco/jacocoagent.jar=$append,$destFile"
    
      createDebugCoverageReport.dependsOn testDebug
    }
    

    这会将单元测试执行数据附加到connectedAndroidTest 生成的覆盖率文件中,因此您的报告会同时反映仪器测试和单元测试,而不是单独反映每个变体。

    请注意,connectedAndroidTest 会覆盖覆盖率文件,请在创建报告时考虑到这一点。如果任务testDebug 没有任何更改,而您运行createDebugCoverageReport,它只会反映您的仪器测试覆盖率。因此,对您的单元测试进行更改。 Linux 命令touch 在这里可能有用,虽然我还没有尝试过。

    【讨论】:

    • 我已经看到了接受的答案。我想。您适合仪器测试和单元测试。我确实需要查看(testDebug.jvmArgs)。非常感谢您解释一些有用的信息。
    • 什么是testDebug,我在哪里添加它?
    • 不适用于 Android Studio 2.1.2 Error:Could not find property 'testDebug' on project ':myproject'。所以我重命名为testDebugUnitTest,但它不处理添加单元测试的覆盖率。
    • @vida 我修复了断开的链接,感谢您告诉我!
    • 我收到错误:错误:(224, 0) 无法获取项目的未知属性“testDebug”。这个怎么解决??
    【解决方案3】:

    今天我确实完全删除了android studio、android sdk、gradle。然后重新安装一切。之后,我只是在应用程序内部添加了 build.gradle。

    debug {
        testCoverageEnabled true
    }
    

    然后我运行 ./gradlew connectedChec。一切正常。 Android Studio 默认 Jacoco 对我来说工作正常。我认为也可以创建一个 jacocoTestReport 任务然后创建代码覆盖率。我不知道为什么 gradle 和 android studio 以前不起作用。

    【讨论】:

      【解决方案4】:

      我研究了使用 Jacoco 获取合并代码覆盖率报告的正确方法,您可以在这里查看:https://gist.github.com/ultraon/54cca81ca159ed0a4a9ebf62e89c26ba

      我将 AndroidStudio 2.2.2 与 Gradle 3.2 和 Android Gradle Plugin 2.2.2 一起使用

      【讨论】:

        猜你喜欢
        • 2015-03-21
        • 2016-11-11
        • 2019-01-02
        • 2012-11-02
        • 2014-11-09
        • 1970-01-01
        • 1970-01-01
        • 2018-05-28
        • 2012-06-11
        相关资源
        最近更新 更多