简体   繁体   English

Jacoco覆盖率报告问题

[英]Jacoco Coverage Report issues

I am trying to define the location, where jacoco will create the coverage file for instrumentation tests running on real devices. 我正在尝试定义位置,jacoco将为真实设备上运行的仪器测试创建覆盖文件。

From the --debug run of the gradle task I see this log: 从gradle任务的--debug运行我看到这个日志:

[DEBUG] [org.gradle.api.Task] DeviceConnector 'Nexus 5X - 6.0.1': installing /home/martin/workspace/lib/my-lib/build/outputs/apk/my-lib-debug-androidTest-unaligned.apk
[INFO] [org.gradle.api.Task] Starting 1 tests on Nexus 5X - 6.0.1
[INFO] [org.gradle.api.Task]  de.my.lib.utils.UtilsTest testMyTest[Nexus 5X - 6.0.1] [32mSUCCESS [0m
[DEBUG] [org.gradle.api.Task] DeviceConnector 'Nexus 5X - 6.0.1': fetching coverage data from /data/data/de.my.lib.test/coverage.ec
[DEBUG] [org.gradle.api.Task] DeviceConnector 'Nexus 5X - 6.0.1': uninstalling de.my.lib.test 13:46:14.538
[DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':my-lib:connectedDebugAndroidTest'

I tried 3 ways to define the location: 我尝试了三种方法来定义位置:

Using the <instrumentation> tag in the manifest file didn't change anything. 使用清单文件中的<instrumentation>标记没有任何改变。

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="de.my.lib.test"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <instrumentation
        android:name="android.support.test.runner.AndroidJUnitRunner"
        xmlns:tools="http://schemas.android.com/tools"
        android:targetPackage="de.my.lib.test"
        tools:replace="android:targetPackage">
        <meta-data
            android:name="coverage"
            android:value="true" />
        <meta-data
            android:name="coverageFile"
            android:value="/sdcard/coverage.ec" />
    </instrumentation>
</manifest>

I tried it with gradle but the output was the same: 我用gradle尝试了它,但输出是相同的:

defaultConfig {
    // unimportant stuff
    testApplicationId "de.my.lib.test"

    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    testInstrumentationRunnerArgument('coverageFile', '/sdcard/coverage.ec')
}

And finally I tried it with adb command: 最后我用adb命令试了一下:

adb shell am instrument -w -e coverage true -e coverageFile /sdcard/coverage.ec de.my.lib.test/android.support.test.runner.AndroidJUnitRunner

But there I get 2 errors: 但在那里我得到2个错误:

de.my.lib.utils.UtilsTest:. de.my.lib.utils.UtilsTest :. Could not find class: org.jacoco.agent.rt.internal_773e439.CoverageTransformer . 找不到类:org.jacoco.agent.rt.internal_773e439.CoverageTransformer。 Time: 0,072 时间:0,072

OK (1 test) 好的(1个测试)

Error: Failed to generate emma coverage. 错误:无法生成emma覆盖率。

I am completely lost here. 我完全迷失在这里。 Any ideas? 有任何想法吗?

Background Why I need it to have it stored in another place: There is a bug with adb shell run-as command on some devices and Android version so I have devices in my test device farm which return 0% coverage because the file can't be pulled. 背景为什么我需要它将它存储在另一个地方:某些设备和Android版本上存在adb shell run-as命令的错误,因此我的测试设备场中的设备返回0%覆盖率因为文件不能被拉。 So I need the file to be stored in a publicly available location. 所以我需要将文件存储在公共场所。

However, the coverage report is not generated yet. 但是,尚未生成覆盖率报告。 To enable this option, we need to add a property to our debug build variant. 要启用此选项,我们需要向调试版本变量添加属性。 Using the Android plugin DSL, we can enable the coverage through the testCoverageEnabled property: 使用Android插件DSL,我们可以通过testCoverageEnabled属性启用覆盖:

android {
    ...
    buildTypes {
        debug {
            testCoverageEnabled true
        }
        ...
    }
}

To enable the coverage report for local tests when using version 2.2.+ of Android Gradle plugin, you need to enable it in your app's build.gradle : 要在使用2.2版本的Android Gradle插件时启用本地测试的覆盖率报告,您需要在应用的build.gradle启用它:

android {
    //...

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

The instrumentation performed by Jacoco produces execution files that contain the necessary data to create the report (HTML, XML, etc.). 通过Jacoco执行的仪器产生包含必要的数据来创建报告(HTML,XML等)执行的文件。 The problem here, is that Espresso generates .ec file, while the unit tests execution generates .exec file… we have different formats! 这里的问题是Espresso生成.ec文件,而单元测试执行生成.exec文件......我们有不同的格式!

As we are not able to configure the coverage task of Espresso, we must ensure that it is executed first. 由于我们无法配置Espresso的覆盖任务,我们必须确保首先执行它。 Next, we need to run unit tests, and then create the coverage data with both files ( ec and exec ). 接下来,我们需要运行单元测试,然后使用两个文件( ecexec )创建coverage数据。

To enable this, we need to edit our task once more and add the coverage.ec file as a parameter in executionData property: 要启用此功能,我们需要再次编辑我们的任务,并将coverage.ec文件添加为executionData属性中的参数:

apply plugin: 'jacoco'

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

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

As Android Gradle plugin 2.2.+ now generates a coverage file for each execution, using the device / emulator in the file name, now we need to pass every file to execution data, as the file name is now dynamic. 由于Android Gradle插件2.2。+现在为每次执行生成一个覆盖文件,使用文件名中的设备/模拟器,现在我们需要将每个文件传递给执行数据,因为文件名现在是动态的。 In addition, I added the createDebugCoverageReport task as a dependency of our custom task, so we don't need to run it manually :) 另外,我添加了createDebugCoverageReport任务作为我们自定义任务的依赖项,因此我们不需要手动运行它:)

Finally, when we execute both tasks, running the Espresso tests first, we will get the unified coverage report! 最后,当我们执行这两项任务时,首先运行Espresso测试,我们将获得统一的覆盖率报告!

gradle clean jacocoTestReport

For detailed explanation see here . 有关详细说明,请参见此处

Edit: 编辑:

So, the command adb shell am instrument does not generates the report, for this you have to handle it using gradle solution. 因此,命令adb shell am instrument不会生成报告,为此您必须使用gradle解决方案来处理它。 If you really want to test it your self, then you've to use a custom runner . 如果你真的想要自己测试它,那么你就要使用自定义跑步者

References: 参考文献:

1) How to Generate Android Testing Report in HTML Automatically 1) 如何自动生成HTML的Android测试报告

2) How to retrieve test results when using "adb shell am instrument" 2) 使用“adb shell am instrument”时如何检索测试结果

3) https://github.com/jsankey/android-junit-report 3) https://github.com/jsankey/android-junit-report


Test from the command line 从命令行进行测试


Updated to Command line method follow these steps. 更新到命令行方法请按照下列步骤操作。

Running the instrumented application 运行已检测的应用程序

Once we have the EmmaInstrumentation class (is in ref link) in place we need a few more adjustments to be able to get the coverage report of the running application. 一旦我们有了EmmaInstrumentation类(在ref链接中),我们需要进行一些调整才能获得正在运行的应用程序的覆盖率报告。

Firstly, we need to add the new Activity to the manifest. 首先,我们需要将新的Activity添加到清单中。 Secondly, we should allow our application to write to the sdcard if this is where we decided to generate the coverage report. 其次,如果我们决定生成覆盖率报告,我们应该允许我们的应用程序写入SD卡。 To do it you should grant the android.permission.WRITE_EXTERNAL_STORAGE permission. 为此,您应该授予android.permission.WRITE_EXTERNAL_STORAGE权限。 Then, it's time to build and install the instrumented apk: 然后,是时候构建和安装检测的apk:

$ ant clean
$ ant instrument
$ ant installi

Everything is ready to start the instrumented application 一切都准备好启动仪表化的应用程序

$ adb shell am instrument -e coverage true \
    -w com.example.i2at.tc/\
        com.example.instrumentation.EmmaInstrumentation

Here is Source code. 是源代码。

the missing CoverageTransformer class hints for a missing dependency to the JaCoCo agent runtime. 缺少的CoverageTransformer类提示缺少对JaCoCo代理运行时的依赖关系。 one simple solution approach might be, to provide it with what it demands (to be available on device): 一种简单的解决方案可能是,为它提供它所需要的(在设备上可用):

testImplementation "org.jacoco:org.jacoco.agent:0.8.3"

in case you get a FileNotFoundException , when the ClassNotFoundException was fixed, make sure to have the permission to write to SD card, which appears to be another possible pitfall: 如果你得到一个FileNotFoundException ,当ClassNotFoundException被修复时,请确保有权写入SD卡,这似乎是另一个可能的陷阱:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

as I've just seen, there is also an org.jacoco.report package, which could be optionally added: 正如我刚才看到的,还有一个org.jacoco.report包,可以选择添加:

testImplementation "org.jacoco:org.jacoco.report:0.8.3"

package org.jacoco.agent is in every case the one which contains class CoverageTransformer . org.jacoco.agent在每种情况下都是包含CoverageTransformer类的包。

For us it was an AOSP app. 对我们来说这是一个AOSP应用程序。 We were generating the test and module apks with disabling Jack compiler which was causing this further issue. 我们正在生成带有禁用Jack编译器的测试和模块apks,这导致了这个进一步的问题。 Because for us Jack compiler was needed to generate coverage.em . 因为对我们来说,Jack编译器需要生成coverage.em But the error was not quite relevant. 但错误并不十分重要。 So had no clue to go any further. 所以没有任何进一步的线索。

So the fix was to run the jack compiler server and get the apks generated using it. 所以解决方法是运行jack编译器服务器并获取使用它生成的apks。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JaCoCo调试覆盖率测试报告 - JaCoCo Debug Coverage Test Report AndroidStudio:JaCoCo代码覆盖率报告的覆盖率为0% - AndroidStudio: JaCoCo code coverage report's 0% for coverage Sonarqube的总体覆盖范围与jacoco报告的覆盖范围不匹配 - Sonarqube overall coverage does not match jacoco report coverage 仪器测试jacoco覆盖率报告始终显示0%覆盖率 - Instrumentation Test jacoco coverage report displays 0% coverage always 测试用例失败后继续 jacoco 代码覆盖率报告 - continue jacoco code coverage report after fail test case Android:无法在azure devops管道上发布Jacoco代码覆盖率报告 - Android : Not able to publish the Jacoco code coverage report on azure devops pipeline Jacoco android 测试覆盖率报告中的文件过滤器未按预期工作 - File filter in Jacoco android test coverage report not working as expected 升级到 AGP 4.2.0,无法生成 Jacoco 代码覆盖率报告 - Upgrade to AGP 4.2.0 ,unable to generate Jacoco code coverage report JaCoCo 覆盖率报告(针对 Kolin)中检测到的“encode()”function 是什么? - What is `encode()` function detected in JaCoCo coverage report (for Kolin)? Jacoco仅针对单个测试类生成覆盖率报告 - Jacoco generate coverage report for only a single test class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM