前言
Android 開發(fā)統(tǒng)計代碼覆蓋率,在之前的老版本中,需要借助第三方工具,在現(xiàn)在的新版本中,只要使用JaCoCo插件,就可以完成簡單覆蓋率測試。
與 Espresso 框架結(jié)合,進(jìn)行覆蓋率測試
Android SDK 現(xiàn)在已經(jīng)內(nèi)置了對 Emma Test Coverage框架的支持,可以在官方文檔中進(jìn)行查閱。 具體由 JaCoCo 工具進(jìn)行覆蓋率相關(guān)內(nèi)容。 1.1 配置: 在 build.gradle 中將 testCoverageEnabled
設(shè)置為 true
android {
buildTypes {
debug {
testCoverageEnabled = true
}
}
}
注:部分資料中,可能寫需要在 build.gradle 中增加如下配置 apply plugin: 'jacoco'
或者 apply plugin: 'jacoco-android'
但是在實(shí)際使用發(fā)現(xiàn),這個配置項(xiàng)并不需要。
使用:
為了能生成代碼覆蓋率報告,我們需要將Android設(shè)備或者模擬器連接到計算機(jī),因?yàn)?在生成報告前,會執(zhí)行 connectedCheck
任務(wù)。 之后,我們可以執(zhí)行如下的命令行
/gradlew clean assemble
此命令會清空所有的編譯產(chǎn)生class,防止之前的測試對后續(xù)造成影響。
/gradlew createDebugCoverageReport
該任務(wù)會分析 /src/main/java/
路徑下的代碼和 /src/androidTest/java/
目錄下測試用例。
在執(zhí)行這個任務(wù)之后,我們可以在模塊的如下路徑中找到代碼覆蓋率報告 /build/outputs/reports/coverage/debug/
我們可以在瀏覽器中打開 index.html 文件,可以看見可視化的報告。 同時,在同一級目錄下,我們也可以找到可以供持續(xù)集成覆蓋率分析使用的 report.xml 文件。
除了上面提到的文件,Gradle也會在如下的路徑創(chuàng)建 coverage.ec
文件。 /build/outputs/code-coverage/connected/
碎片化帶來的問題
由于 Espresso 需要在真機(jī)或者虛擬機(jī)上運(yùn)行,由于android碎片化嚴(yán)重,經(jīng)常出現(xiàn)各種問題。現(xiàn)進(jìn)行一個問題與解決方案的匯總。
小米的問題
問題現(xiàn)象:小米手機(jī)異常:com.android.ddmlib.InstallException: Failed to establish session
解決方案:在開發(fā)者選項(xiàng)中,關(guān)閉 MIUI 優(yōu)化選項(xiàng)。 http://en.miui.com/thread-255506-1-1.html
與 Robolectric 框架結(jié)合,進(jìn)行覆蓋率測試
谷歌對 Robolectric
框架支持力度一般,所以發(fā)現(xiàn) JaCoCo 工具在使用此框架時候,需要進(jìn)行的配置較多。
配置
在 build.gradle 中將 testCoverageEnabled
設(shè)置為 true
android {
buildTypes {
debug { testCoverageEnabled = true }
}
}
在 build.gradle 中增加如下配置
apply plugin: 'jacoco'
此框架中需要此配置。 然后在 gradle 文件中插入如下的配置,對JaCoCo進(jìn)行設(shè)置
jacoco {
toolVersion = "0.7.1.201405082137" //版本號可用最新
}
def coverageSourceDirs = [
'../app/src/main/java'
]
task jacocoTestReport(type:JacocoReport, dependsOn: "testDebugUnitTest") {
group = "Reporting"
description = "Generate Jacoco coverage reports"
classDirectories = fileTree(
dir: '../app/build/intermediates/classes/debug',
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*'] // 去掉不進(jìn)行檢查的文件
)
additionalSourceDirs = files(coverageSourceDirs)
sourceDirectories = files(coverageSourceDirs)
executionData = files('../app/build/jacoco/testDebugUnitTest.exec')
reports {
xml.enabled = true
html.enabled = true
}
}
task jacocoTestReport(type:JacocoReport, dependsOn: "testDebugUnitTest")
這行的配置,中間的dependsOn
一定要設(shè)置成 testDebugUnitTest 后續(xù)才可以正確執(zhí)行覆蓋率測試。
https://github.com/kvandermast/my-robolectric-app
在這個例子中,此配置成了 testDebug
,實(shí)際測試發(fā)現(xiàn)會報錯 Task 'jacocoTestReport' not found in root project '<project name>'.
使用
先執(zhí)行如下的命令行,清除之前的殘留配置。
/gradlew clean testDebugUnitTest jacocoTestReport
之后再執(zhí)行命令行
/gradlew jacocoTestReport
執(zhí)行該命令行后,會執(zhí)行所有的單元測試用例,然后在如下位置生成報告。 build/reports/jacoco/jacocoTestReport/html 也可以通過瀏覽器對覆蓋率情況進(jìn)行查看
同時使用兩個框架進(jìn)行覆蓋率測試
以為兩個配置并不相同,可能會相互影響,網(wǎng)上也有不少解決方案,但是始終都是要修改gradle文件。
如:http://www.itdecent.cn/p/4b03123b4f81
后來經(jīng)過嘗試發(fā)現(xiàn)。按照上述1, 2步驟配置后,兩個框架的測試用例覆蓋率檢測其實(shí)并不沖突。 也就是說在配置好后,如果需要使用Espresso進(jìn)行集成測試統(tǒng)計覆蓋率,則執(zhí)行如下命令
/gradlew clean assemble
/gradlew createDebugCoverageReport
如果需要使用Robolectric執(zhí)行單元測試統(tǒng)計覆蓋率,則執(zhí)行如下命令
/gradlew clean testDebugUnitTest jacocoTestReport
/gradlew jacocoTestReport
可以分別生成覆蓋率報告
與 Jenkins CI 的結(jié)合
為了能在 Jenkins CI 上發(fā)布報告,可以使用代碼覆蓋率插件,但是并不能確認(rèn)插件的穩(wěn)定性。另一種解決方案是 HTML Publisher plugin,我們可以增加相應(yīng)動作,在 Jenkins 的任務(wù)中,通過默認(rèn)的HTML界面產(chǎn)生覆蓋率報告,我認(rèn)為這是一種非常方便的方式,易于創(chuàng)建,并且方便進(jìn)行代碼導(dǎo)航,能定位到?jīng)]有覆蓋的代碼行,方法和分支。
參考文檔
http://blog.wittchen.biz.pl/test-coverage-report-for-android-application/ 已翻譯,中文鏈接如下:
https://github.com/weijianfeng/Translation-Project/blob/master/Project/1/Test%20coverage%20report%20for%20Android%20application.md
https://github.com/kvandermast/my-robolectric-app
https://github.com/aresLove/android-tech-frontier/tree/master/issue-7/%E4%BD%BF%E7%94%A8Robolectric%E5%92%8CAndroid%E7%94%9F%E6%88%90%E4%BB%A3%E7%A0%81%E8%A6%86%E7%9B%96%E7%8E%87%E6%8A%A5%E5%91%8A
http://www.itdecent.cn/p/4b03123b4f81