[英]Jacoco and Unit Tests Code Coverage with android-gradle-plugin >= 1.1
我最近開始在其中一個項目中集成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
。 。
可能是我失去了使用Google的能力。 但是有人可以指出我可以在android gradle插件中找到有關新內容的文檔以及如何僅針對單元測試運行jacoco任務的方向嗎?
更新
從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(零)測試覆蓋率,這是不可能的,因為至少所有類中的一半都經過了測試。
UPDATE_2
試了這個例子 。 將下一個任務添加到我的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 apply plugin: 'com.android.application'
的模塊apply plugin: 'com.android.application'
(報告正確生成了)。 但是對於屬於android庫的模塊( apply plugin: 'com.android.library'
),報告顯示的覆蓋率為零,盡管這些模塊比應用程序模塊包含更多的測試。
UPDATE_4
創建了一個簡單的示例項目來演示我的問題。 當前,如果您運行./gradlew jacocoReport
,則會生成報告,但不會顯示模塊項目的測試覆蓋率。 看到這個鏈接
簡短說明:當測試為AndroidUnitTests(白色JUnit 4和Robolectric)時,JaCoCo報告顯示了所有模塊的覆蓋范圍。
有任何想法嗎?
麻煩之后,我決定為此創建一個開源Gradle插件 。
根build.gradle
buildscript {
repositories {
mavenCentral() // optional if you have this one already
}
dependencies {
classpath 'com.vanniktech:gradle-android-junit-jacoco-plugin:0.8.0'
}
}
apply plugin: 'com.vanniktech.android.junit.jacoco'
然后簡單地執行
./gradlew jacocoTestReportDebug
它將在調試模式下運行JUnit測試,然后在相應的構建目錄中以xml和html格式提供Jacoco輸出。
它還支持口味。 有兩種口味的紅色和藍色將創建這些任務
經過一些額外的搜索后,我偶然發現了這個項目,我不得不進行一些修改,以使解決方案適用於我的項目類型,但是現在可以正確生成測試覆蓋率報告。
我已將采用的更改推送到我的示例github存儲庫中,以防將來有人遇到類似問題。
我使用此博客文章為gradle 1.2設置了單元測試。 然后,我整理了在這里和其他地方找到的信息,以將代碼覆蓋率添加到獨立模塊而不是整個項目中。 在我的庫模塊build.gradle
文件中,添加了以下內容:
apply plugin: 'jacoco'
def jacocoExcludes = [
'com/mylibrary/excludedpackage/**'
]
android {
...
}
android.libraryVariants.all { variant ->
task("test${variant.name.capitalize()}WithCoverage", type: JacocoReport, dependsOn: "test${variant.name.capitalize()}") {
group = 'verification'
description = "Run unit test for the ${variant.name} build with Jacoco code coverage reports."
classDirectories = fileTree(
dir: variant.javaCompile.destinationDir,
excludes: rootProject.ext.jacocoExcludes.plus(jacocoExcludes)
)
sourceDirectories = files(variant.javaCompile.source)
executionData = files("${buildDir}/jacoco/test${variant.name.capitalize()}.exec")
reports {
xml.enabled true
xml.destination "${buildDir}/reports/jacoco/${variant.name}/${variant.name}.xml"
html.destination "${buildDir}/reports/jacoco/${variant.name}/html"
}
}
}
在我的項目build.gradle
文件中,添加了常見的排除項:
ext.jacocoExcludes = [
'android/**',
'**/*$$*',
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Service.*'
]
另外,看起來單元標記的代碼覆蓋范圍可能會在將來的版本144664中構建
警告:這是駭客! 使用上面的配置,我整理了一個技巧,根據選擇的構建任務在應用程序和庫之間切換android插件。 這對我來說效果很好,因為我最終不會在設置應用程序模式的情況下提交代碼。
// dynamically change the android plugin to application if we are running unit tests or test reports.
project.ext.androidPlugin = 'com.android.library'
for (String taskName : project.gradle.startParameter.taskNames) {
if (taskName.contains('UnitTest') || taskName.contains('jacocoTestReport')) {
project.ext.androidPlugin = 'com.android.application'
break
}
}
logger.lifecycle("Setting android pluging to ${project.ext.androidPlugin}")
apply plugin: project.ext.androidPlugin
...
apply plugin: 'jacoco'
configurations {
jacocoReport
}
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
}
}
希望android工具團隊盡快解決此問題。
我終於能夠看到使用Android Studio 1.1進行JUnit測試的代碼覆蓋率。
jacoco.gradle
apply plugin: 'jacoco'
jacoco {
toolVersion "0.7.1.201405082137"
}
def coverageSourceDirs = [
"$projectDir/src/main/java",
]
task jacocoTestReport(type: JacocoReport, dependsOn: "testDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml.enabled = true
html.enabled = true
}
classDirectories = fileTree(
dir: './build/intermediates/classes/debug',
excludes: ['**/R*.class',
'**/*$InjectAdapter.class',
'**/*$ModuleAdapter.class',
'**/*$ViewInjector*.class'
]
)
sourceDirectories = files(coverageSourceDirs)
executionData = files("$buildDir/jacoco/testDebug.exec")
// Bit hacky but fixes https://code.google.com/p/android/issues/detail?id=69174.
// We iterate through the compiled .class tree and rename $$ to $.
doFirst {
new File("$buildDir/intermediates/classes/").eachFileRecurse { file ->
if (file.name.contains('$$')) {
file.renameTo(file.path.replace('$$', '$'))
}
}
}
}
然后在模塊的build.gradle文件中(我將其放在android
和dependencies
之間):
apply from: '../jacoco.gradle'
也在android
的defaultConfig
塊中。 我添加了此內容(不知道是否有必要,但是我從此Blog中獲得了此內容):
android {
defaultConfig {
testHandleProfiling true
testFunctionalTest true
}
}
請享用。
您可以嘗試使用此Gradle插件: https : //github.com/arturdm/jacoco-android-gradle-plugin
基本上,您需要做的就是像這樣應用它:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
}
}
apply plugin: 'com.android.library' // or 'com.android.application'
apply plugin: 'jacoco-android'
結果,您應該為每個變量獲得一個JacocoReport
任務。 運行以下命令以生成所有代碼覆蓋率報告。
$ ./gradlew jacocoTestReport
我解決了JaCoCo的問題,並使其與最新的gradle android插件1.1.3一起使用
具有最新gradle腳本的項目: https : //github.com/OleksandrKucherenko/meter
參考文獻:
如何在Android Studio單元測試中附加自己的實現而不是Mocks? https://plus.google.com/117981280628062796190/posts/8jWV22mnqUB
對嘗試在Android構建中使用JaCoCo覆蓋范圍的所有人的一個小提示...意外發現!!! https://plus.google.com/117981280628062796190/posts/RreU44qmeuP
JaCoCo用於單元測試的XML / HTML報告 https://plus.google.com/u/0/+OleksandrKucherenko/posts/6vNWkkLed3b
我正面臨着像你一樣的問題。 今天我確實完全刪除了android studio,android sdk,gradle。 然后重新安裝所有內容。 之后,我只添加了應用程序build.gradle。
debug {testCoverageEnabled true}然后運行./gradlew connectedChec。 一切工作正常。 Android studio默認的Jacoco對我來說工作正常。 我認為也可以創建一個jacocoTestReport Task然后創建代碼覆蓋率。我不知道為什么gradle和android studio以前無法正常工作。
請創建一個示例,我可以看看。 我想這是一些缺少的路徑配置。
這里有兩個例子
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.