[英]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
andexec
).接下来,我们需要运行单元测试,然后使用两个文件(
ec
和exec
)创建coverage数据。To enable this, we need to edit our task once more and add the
coverage.ec
file as a parameter inexecutionData
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 . 有关详细说明,请参见此处
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
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.