何番煎じなのか分かりませんが、Gradleが6系になりまた記述方法が変わったりしたので気にせずに記事にします。
- Gradle: 6.0.1
- Android Gradle Plugin: 3.5.3
の環境で検証しています。
また、カバレッジの算出に不要な記述は省いています。
実際のプロジェクトでどのように書くか気になる場合は以下を参照
https://github.com/ohmae/touch-icon-extractor
シングルモジュール
まずはマルチモジュールの前に各モジュールの中でのカバレッジ算出です。
apply plugin: "jacoco"
android {
testOptions {
unitTests.includeAndroidResources = true
unitTests.all {
jacoco {
includeNoLocationClasses = true
}
}
}
}
jacoco {
toolVersion = "0.8.5"
}
task jacocoTestReport(
type: JacocoReport,
dependsOn: "testDebugUnitTest",
group: "verification"
) {
reports {
xml.enabled = true
html.enabled = true
}
getSourceDirectories().from = "${projectDir}/src/main/java"
getClassDirectories().from = fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug")
getExecutionData().from = "${buildDir}/jacoco/testDebugUnitTest.exec"
}
これだけです。ビルドバリアントに依存する部分がありますので、その部分は適宜書き換えてください。
android {
testOptions {
unitTests.all {
jacoco {
includeNoLocationClasses = true
}
}
}
}
上記の記述がないと、Robolectricを使ったテストのカバレッジが算出できません。
getClassDirectories().from = fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug")
上記の部分はコンパイルされたクラスファイルの指定です、Androidでは自動的に生成されるクラスを除外する記述を行いますが、(現時点では)javaとkotlinでクラスファイルの場所が違っており、フルKotlinのプロジェクトならKotlinのクラスファイルを指定するだけで除外する必要はありません。
マルチモジュール
マルチモジュールでプロジェクト全体のカバレッジを出すには、各プロジェクトごとのカバレッジ情報を集める必要があります。
これはルートプロジェクトのGradleファイル上でタスクを定義します。
apply plugin: "jacoco"
jacoco {
toolVersion = "0.8.5"
}
task jacocoMerge(
type: JacocoMerge,
group: "verification"
) {
gradle.afterProject { project, _ ->
if (project.rootProject != project && project.plugins.hasPlugin('jacoco')) {
executionData "${project.buildDir}/jacoco/testDebugUnitTest.exec"
}
}
}
task jacocoMergedReport(
type: JacocoReport,
dependsOn: [tasks.jacocoMerge],
group: "verification"
) {
getExecutionData().from = jacocoMerge.destinationFile
gradle.afterProject { project, _ ->
if (project.rootProject != project && project.plugins.hasPlugin('jacoco')) {
getSourceDirectories().from += "${project.projectDir}/src/main/java"
getClassDirectories().from += project.fileTree(dir: "${project.buildDir}/tmp/kotlin-classes/debug")
}
}
reports {
xml.enabled = true
html.enabled = true
}
}
ルートプロジェクトはサブプロジェクトよりも先に評価されるため。そのままではサブプロジェクトの情報を集められない。
gradle.afterProject
を使って、各プロジェクトが評価された後にクロージャを経由して情報を収集する。
クロージャではルートプロジェクト自身と、Jacocoを使っていない、カバレッジ算出対象外のプロジェクトを除外しています。
モジュールごとの算出と同じものを集めているだけといった形です。
jacocoMergeの依存関係で各モジュールのテスト実行をさせたかったのですがうまくいかず、補足いただけると幸いです。
以上です。