Help us understand the problem. What is going on with this article?

Gradle6系 + Jacoco + マルチモジュール + フルKotlin + Android + Robolectric環境でユニットテストのカバレッジを出す

何番煎じなのか分かりませんが、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の依存関係で各モジュールのテスト実行をさせたかったのですがうまくいかず、補足いただけると幸いです。

以上です。

ryo_mm2d
Yahoo! JAPANでAndroidアプリを作っています。趣味はソフト開発!結果にコミットするよりGithubにコミットする生活を送っています。 https://github.com/ohmae/curriculum-vitae
https://www.mm2d.net/
yahoo-japan-corp
Yahoo! JAPAN を運営しています。
https://www.yahoo.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした