问题描述
我最近开始在我的一个项目中集成 android-gradle-plugin 1.1.0.该项目使用 robolectric 2.4 来运行单元测试.
I recently started integrating android-gradle-plugin 1.1.0 in one of my projects. The project uses robolectric 2.4 to run unit tests.
这是一个多模块项目,具有非常复杂的依赖关系(一些模块依赖于其他模块).类似的东西:
It's a multi module project with very complex dependencies (Some modules depend on other modules). Something like that:
--> 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 项目.
For a more cleared picture please see jacoco-example project.
我试图集成 JaCoCo 来为单元测试生成报告,但在我看来它只运行 androidTests 基本上是仪器测试.
I tried to integrate JaCoCo to generate reports for the unit tests, but it seems to me that it runs only androidTests which are basically instrumentation tests.
经过一些谷歌搜索后,我在 GitHub 和其他文章上遇到了一些项目,但它们主要集中在以前版本的 android-gradle-plugin 或正在使用其他第三方android-unit-test 例如这里这样的插件.
After some google'ing I've come across a few projects on GitHub and other articles, but they mainly are focused on previous versions of the android-gradle-plugin or are using other third party plugins like android-unit-test for example here.
可能是我失去了使用谷歌搜索的能力.但是有人可以指出我可以找到一些关于 android gradle 插件中的新内容以及如何仅针对单元测试运行 jacoco 任务的文档的方向吗?
May be I've lost my ability to google. But can somebody point me in a direction where I can find some documentations regarding the new stuff in android gradle plugin and how to run the jacoco task only for unit tests?
更新
采用 nenick 的例子的脚本:
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(零)测试覆盖率,这是不可能的,因为至少有一半的类都经过测试.
After that the ./gradlew jacocoReport executes and generates the report, but it shows 0 (zero) test coverage, which is impossible because at least half of all classes are tested.
UPDATE_2
试用了这个示例.将下一个任务添加到我的一个 gradle 构建文件中:
Tried out this example. Adding the next task to one of my gradle build files:
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 } }
同样的问题,生成了报告,但代码覆盖率仍然为零.
Same issue, the reports are generated, but the code coverage is still zero.
UPDATE_3
UPDATE_2 中的任务似乎有效,但仅适用于带有 apply plugin: 'com.android.application' 的模块(报告正确生成).但是对于 android 库模块(apply plugin: 'com.android.library'),报告显示零覆盖率,尽管模块包含的测试比应用程序模块多.
It seams that the task from UPDATE_2 worked but only for the module with apply plugin: 'com.android.application' (The reports a generated correctly). But for modules that are android libraries (apply plugin: 'com.android.library') the reports show zero coverage, although the modules contain more tests then the application module.
UPDATE_4
创建了一个简单的示例项目来演示我的问题.目前,如果您运行 ./gradlew jacocoReport 会生成报告,但不会显示模块项目的测试覆盖率.请参阅此 链接
Created a simple example project that demonstrates my issue. Currently if you run ./gradlew jacocoReport the report is generated, but no test coverage is displayed for the module projects. See this link
简短说明:当测试是 AndroidUnitTests(白化 JUnit 4 和 Robolectric)时,JaCoCo 报告显示了所有模块的覆盖范围.
Short note: When the tests were AndroidUnitTests (whiteout JUnit 4 and Robolectric) JaCoCo reports showed coverage for all the modules.
有什么想法吗?
推荐答案
经过一番折腾,我决定创建一个 开源 Gradle 插件 .
After the hassle, I decided to create an open source Gradle plugin for that.
根 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
它将在调试模式下运行 JUnit 测试,然后在相应的构建目录中以 XML 和 HTML 形式为您提供 Jacoco 输出.
It'll run the JUnit tests in Debug Mode and then give you the Jacoco output in XML and HTML form in the corresponding build directory.
它还支持风味.将创建红色和蓝色 2 种口味的任务
It also supports flavors. Having 2 flavors red and blue those tasks would be created
- jacocoTestReportRedDebug
- jacocoTestReportBlueDebug
- jacocoTestReportRedRelease
- jacocoTestReportBlueRelease