Kover によるカバレッジレポート出力について、対象クラスを限定する

この記事は「[Kover でらくらく！ Android のカバレッジレポート出力](https://qiita.com/tfandkusu/items/a6cf3dd42bb699986245)」の応用編となります。

# はじめに

[先日公開した記事](https://qiita.com/tfandkusu/items/a6cf3dd42bb699986245)では、Android の[ローカル単体テスト](https://developer.android.com/training/testing/unit-testing/local-unit-tests)のカバレッジレポート出力について、以前から使われていた [JaCoCo Plugin](https://docs.gradle.org/current/userguide/jacoco_plugin.html) より設定が簡単な [Kover](https://github.com/Kotlin/kotlinx-kover) を使って、CI でカバレッジレポートを出力する Gradle タスクを実行し [Codecov](https://about.codecov.io/) にアップロードしてチーム共有を行う方法を説明しました。

## 応用編として対象クラスを限定する方法を紹介

今回は前回説明しなかった対象クラスを限定する設定を紹介することで、Codecov を使わないケースでも Kover を適切に扱う方法を紹介します。また、Codecov の有無は問わず、例えば ViewModel に限定したカバレッジレポートがほしいケースにも対応します。

## 前提条件

この記事では、前回の記事で紹介した Gradle の設定はすでに完了している前提で解説します。

- [Kover のミニマムな設定方法](https://qiita.com/tfandkusu/items/a6cf3dd42bb699986245#kover-%E3%81%AE%E3%83%9F%E3%83%8B%E3%83%9E%E3%83%A0%E3%81%AA%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95)
- [マルチモジュールの場合](https://qiita.com/tfandkusu/items/a6cf3dd42bb699986245#%E3%83%9E%E3%83%AB%E3%83%81%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%AE%E5%A0%B4%E5%90%88)

## Codecov を使わずに HTML 形式のカバレッジレポートを運用する例

Codecov は有料サービスのため予算の制約があるチームでは使えないことがあります。[2023年7月7日現在、年額プランで1人10ドル/月かかります。](https://about.codecov.io/pricing/)(個人開発や学習等で1人で使う場合は月 250 PUSH まで無料です。)また自社セキュリティポリシーに合わないケースもあると思います。その場合は HTML 形式のカバレッジレポートを出力して運用する方法があります。例えば GitHub Actions にはビルドの生成物である Artifacts をアップロードする機能があります。

```.github/workflows/check.yml
name: check
on:
  push:
    branches:
      - main
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
jobs:
  check:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - uses: actions/setup-java@v3
        with:
          distribution: 'adopt'
          java-version: '17'
      - uses: gradle/gradle-build-action@v2
      # 単体テストの実行 + HTML 形式のカバレッジレポート出力
      - run: ./gradlew koverHtmlReportDebug
      # Artifacts としてカバレッジレポートをアップロード
      - uses: actions/upload-artifact@v3
        with:
          # ファイル名は coverage.zip
          name: coverage
          # カバレッジレポート出力先ディレクトリ
          path: app/build/reports/kover/htmlDebug/
```

ワークフローの実行結果の Summary から ZIP 形式でダウンロードできます。

![スクリーンショット 2023-07-07 0.22.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/2e8a79f3-3222-cb43-9fde-819b56d8f05e.png)

しかし、前回の説明だけでは [Hilt](https://developer.android.com/training/dependency-injection/hilt-android) 等によって自動生成されたクラスも HTML 形式のカバレッジレポートに載ってしまいます。今回は必要な情報だけを HTML 形式のカバレッジレポートに載せる方法を解説します。

![スクリーンショット 2023-07-07 0.32.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/67637f58-28a8-dcf5-89f7-21edca1ec7ae.png)

# カバレッジレポート対象クラスを限定する

前回の説明だけでは、Codecov を使用してリポジトリ上の kt ファイルに限定しても、通常ローカル単体テストを書くことが無い Activity や Composable 関数等もカバレッジレポートに含まれてしまいます。ここでは Kover の設定によって、無駄の無いカバレッジレポートの作成を目指します。

## カバレッジレポートの例

### すべてのクラスを対象にしたカバレッジレポート

![スクリーンショット 2023-07-08 0.44.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/208afbc9-822c-2b17-91c5-c9f2a6b68ae0.png)

![スクリーンショット 2023-07-08 0.57.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/e513aa89-8833-bb94-c7aa-b60e3fcb57ed.png)

### 単体テスト対象のクラスだけを対象にしたカバレッジレポート

![スクリーンショット 2023-07-08 0.42.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/a3bbab16-153a-c663-e8c6-81db12d41837.png)

## 設定方法

設定方法は[公式ドキュメント「Kover Gradle Plugin」の Filtering reports 節](https://kotlin.github.io/kotlinx-kover/gradle-plugin/#filtering-reports)にあります。

`koverReport` `filters` `includes` ブロックで対象クラスを指定して `excludes` ブロックで除外するクラスを指定できます。`*` でその部分が任意のパッケージ名およびクラス名にマッチします。

例えば ViewModel クラスに限定してカバレッジレポートを出力したい場合は app モジュールの build.gradle にこのように書きます。

```app/build.gradle
koverReport {
    filters {
        includes {
            classes("*ViewModel")
        }
    }
}
```

もしインターフェースと実装クラスが別にある場合は間違えないようにご注意ください。実装クラスの方を指定します。

また、例えば [Hilt](https://developer.android.com/training/dependency-injection/hilt-android) と [Room](https://developer.android.com/training/data-storage/room) による自動生成クラスを除外したい場合はこのように書きます。


```app/build.gradle

koverReport {
    filters {
        excludes {
            classes(
                    "*.BuildConfig",
                    // Hilt による自動生成
                    "hilt_aggregated_deps.*", "dagger.*", "*_Factory", "*_*Factory*",
                    "*.Hilt_*", "*_HiltModules*",
                    // Room による自動生成
                    "*_Impl*",
            )
        }
    }
}
```

このあたりは、使用するライブラリやそのバージョンによっても異なるので `koverHtmlReportDebug` Gradle タスクで HTML 形式のカバレッジレポートを出力しながら調整するのが良いと思います。後ろの `*` はサブクラス含めてを除外するために使っています。