 笹川(エンジニア)
笹川(エンジニア)Androidのユニットテストの重要性、カバレッジの計測と向上テクニック
 笹川(エンジニア)
笹川(エンジニア)IT技術

Androidでもユニットテストは大事!
モバイルメインで色々開発している笹川(ささがわ)です!
アプリ開発において、新しい機能を追加したり、古いコードをリファクタリングしたりする際、こんな不安を感じたことはありませんか?「この変更、どこか別のところに影響しないかな...?」
この不安を解消し、自信を持ってコードを改善していくための土台となるのが、ユニットテストです。
今回は、なぜユニットテストがエンジニアの必須スキルなのかを再確認し、具体的なカバレッジの計測・向上方法までを解説していきます。
1. なぜユニットテストはエンジニアの必須スキルなのか?
ユニットテストは単なる「バグを見つける作業」ではありません。
それは、開発プロセス全体を支える「リファクタリングの保険」であり、コードの「設計を改善する指標」でもあります。
- リファクタリングの保険:
 テストがあれば、大規模な変更を加えた後でも、「テストが通っているから大丈夫」という確信のもとにリリースできます。テストがないコードは、変更を加えるたびに潜在的なバグを生み出すリスクを抱えてしまいます。
- 高速なフィードバックサイクル:
 エミュレータを起動してUIを操作する(インストゥルメンテッドテスト)よりも、JVM上で数秒で実行できるユニットテストは圧倒的に高速です。この高速なフィードバックが、開発のテンポを崩しません。
 あわせて、CIによる定期実行やプルリクエスト作成時の自動実行をすることでテスト確認忘れがあってもすぐに検知ができます。
2. ユニットテストのスコープと対象の優先順位
「どこからテストを書くべきか」という疑問は、多くのエンジニアが抱えるものです。
リソースを最適に使うため、テスト対象の優先順位を明確にしましょう。
- Unit Test (JVM Test) の定義:
 AndroidのOS環境(ContextやResourcesなど)に依存せず、外部依存(データベース、ネットワークAPIなど)をmockやfakeで分離し、JVM上で実行する非常に高速なテストです。
- テスト対象の優先順位:
| レイヤー | テスト対象 | なぜ優先度が高いか | 
|---|---|---|
| Domain Layer (ユースケース) | ビジネスロジックの核。入力と出力が明確なロジック。 | アプリの最も重要な価値であり、バグが許されない部分だからです。 | 
| ViewModel | 状態管理のフロー、非同期データの変換ロジック。 | UIに直結するロジックであり、UIテストよりも高速に検証できるからです。 | 
| Data Layer (リポジトリ) | データ変換(APIモデル → Domainモデル)やキャッシュの振る舞い。 | データ操作の信頼性を確保するためです。 | 
このように、ビジネスロジックやデータ変換など、「純粋なロジック」の部分からテストを厚くしていくのが、最もコストパフォーマンスの高い戦略です。
3. カバレッジの計測方法(Jacocoの活用)
「どれくらいテストを書いたか」を客観的に示す指標が、テストカバレッジです。
Androidプロジェクトでは、主にJacoco(Java Code Coverage)というツールを使って計測します。
Jacocoによる計測設定の基本
Jacocoは、Gradleファイルに設定を追加することで、簡単にカバレッジレポートを生成できます。
1
2// app/build.gradle.kts (Kotlin DSLの場合)
3android {
4    buildTypes {
5        debug {
6            // debugビルドでのみカバレッジ計測を有効にする
7            enableAndroidTestCoverage = true
8            enableUnitTestCoverage = true
9        }
10    }
11}
12
13// build.gradle.kts(プロジェクトルート)にJacocoプラグインを適用し、
14// testReportタスクでレポートを生成する設定を追加します。カバレッジレポートの読み方
Jacocoレポートで見るべき主な指標は以下の2つです。
- Line Coverage(ラインカバレッジ):
 コードの「行」がテストによって実行された割合です。
- Branch Coverage(ブランチカバレッジ):
 if文やwhen式など、条件分岐の「パス」がテストによって網羅された割合です。こちらの方が、より質の高いテストが書かれているかを示します。
カバレッジレポートは、HTML形式で生成されるため、どのファイル、どの行がテストされていないかが一目瞭然で分かります。
4. 実践:カバレッジを上げるための具体的なテクニック
カバレッジが低い箇所を見つけたら、以下のテクニックを使ってテストを書いていきます。
1. Mockingによる依存関係の分離
テスト対象のクラスが外部ライブラリや他のクラス(例:ApiServiceClient, RoomDao)に依存している場合、それらをMock(模擬オブジェクト)に置き換えて分離します。
- 使用ツール:MockK(Kotlin向け)が主流です。
- 目的: テスト対象の「ユニット」以外の外部要因による失敗を防ぎ、テストの信頼性を高めます。
2. Fake/Stubによる実装の代用
特にリポジトリのテストなどで、本物のデータベース接続やネットワーク処理を実行したくない場合に有効です。
- 手法: 実際のRoomDaoインターフェースを実装したFakeDaoクラスをテストコード側に作成し、データをMutableListなどのインメモリで保持・操作させます。
- 目的: 複雑な依存関係をシンプルなインメモリ実装に置き換え、テストを高速化します。
3. カバレッジ計測対象の絞り込み
不必要なコードがカバレッジを下げている場合があります。これらをレポートから除外することで、ビジネスロジックに集中できます。
- 除外対象の例:
 自動生成されたファイル(DaggerやHiltのコード、ViewBindingのクラスなど)。
- データクラス(data class)のequals()やhashCode()など、Kotlinが自動生成する関数。
GradleのJacoco設定で、これらのファイルをパターンマッチングで除外することで、カバレッジの数値がよりビジネスロジックの品質を反映したものになります。
まとめ:カバレッジは手段であり、目的ではない
ユニットテストのカバレッジを追うことは、コードの品質を担保する上で非常に有効な手段です。
しかし、最も大切なことは、カバレッジの数字そのものではなく、重要なビジネスロジックがしっかりテストされているかという点です。
まずはJacocoを導入し、ご自身のアプリのテストカバレッジが現在どれくらいなのかを確認するところから始めてみましょう。
そして、テストが薄い部分、すなわち「リファクタリングの保険」が手薄な部分から、テストコードを追加してみてください。
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ

新潟生まれ新潟育ち本業はモバイルアプリエンジニア。 日々、猫(犬)エンジニアとして活躍中!












