https://developer.android.com/training/testing/start/index.html
src/test/java
以下に書いていくテストは、"Local Unit Test"というそうです。
一方、src/androidTest/java
以下に書くテストは、"Instrumented Test"というそうです。
今のプロジェクトでは、テストの実行速度を優先して"Local Unit Test"を書いており、またそのカバレッジを取得しようとしています。
なので、その設定をまとめました。
実際には、
https://blog.gouline.net/code-coverage-on-android-with-jacoco-92ec90c9355e#.elikwgbjp
に書いてあることがほとんどです。
最終的に設定したものが、 https://github.com/noboru-i/kyouen-android/pull/26 のPRにまとまってます。(daggerも同時に入れてしまっていますが)
gradleスクリプトを記述
tasks/jacoco.gradle
として、下記のスクリプトを置いておきます。
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.7.6.201602180812"
}
project.afterEvaluate {
// Grab all build types and product flavors
def buildTypes = android.buildTypes.collect { type ->
type.name
}
def productFlavors = android.productFlavors.collect { flavor ->
flavor.name
}
// When no product flavors defined, use empty
if (!productFlavors) productFlavors.add('')
productFlavors.each { productFlavorName ->
buildTypes.each { buildTypeName ->
def sourceName, sourcePath
if (!productFlavorName) {
sourceName = sourcePath = "${buildTypeName}"
} else {
sourceName = "${productFlavorName}${buildTypeName.capitalize()}"
sourcePath = "${productFlavorName}/${buildTypeName}"
}
def testTaskName = "test${sourceName.capitalize()}UnitTest"
// Create coverage task of form 'testFlavorTypeCoverage' depending on 'testFlavorTypeUnitTest'
task "${testTaskName}Coverage"(type: JacocoReport, dependsOn: "$testTaskName") {
group = "Reporting"
description = "Generate Jacoco coverage reports on the ${sourceName.capitalize()} build."
classDirectories = fileTree(
dir: "${project.buildDir}/intermediates/classes/${sourcePath}",
excludes: [
'**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*$Lambda$*.class'
]
)
def coverageSourceDirs = [
"src/main/java",
"src/$productFlavorName/java",
"src/$buildTypeName/java"
]
additionalSourceDirs = files(coverageSourceDirs)
sourceDirectories = files(coverageSourceDirs)
executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")
reports {
xml.enabled = true
html.enabled = true
}
}
}
}
}
gradleスクリプトを適用する
app/build.gradle
に下記の記述を追加します。
apply from: '../tasks/jacoco.gradle'
タスクの実行
./gradlew :app:testDebugUnitTestCoverage
を実行します。
app/build/reports/jacoco/testDebugUnitTestCoverage/html/index.html
にhtml形式で結果が出力されています。
その他メモ
excludesの設定
リンク元では '**/*$Lambda$*.class'
は無かったですが、retrolambdaで生成したクラス部分でエラーになったので、 追加しました。
どこかのページを参考にした気がするのですが、忘れてしまいました。
https://github.com/evant/gradle-retrolambda/issues/145 を見ると、いくつかのバージョンでは動作するようです。
ほかにもこういった変換を行っているライブラリを使う際には、追加が必要なのかもしれないです。