高度なテスト設定

基本的なテスト構成をセットアップして実行する方法は、Android Studio でテストするコマンドラインからテストするに記載されています。ただし、アプリとそのテスト要件が高度になるほど、テスト構成の調整が必要になります。たとえば次のようなことを行う場合、高度なテストのセットアップが必要になります。

  • 特定のビルド バリアントに対してのみインストルメンテーション テストを実行するか、そのマニフェスト設定をオーバーライドする。
  • テストを実行するビルドタイプを変更するか、その Gradle オプションを構成する。
  • インストルメンテーション テストを独自のテスト モジュールに抽出する。
  • 継続的インテグレーション セットアップの一環として、さらに高度なテストを行う。

このページでは、デフォルト設定がニーズに合わない場合にテストを構成するさまざまな方法について説明します。

ビルド バリアントに応じたインストルメンテーション テストを作成する

一意のソースセットを持つビルド バリアントがプロジェクトに含まれている場合は、そのソースセットに対応するインストルメンテーション テストを用意することをおすすめします。そうすると、テストコードを整理でき、特定のビルド バリアントに適用されるテストのみを実行できます。

インストルメンテーション テストをビルド バリアントにリンクするには、src/androidTestVariantName にある独自のソースセットに配置します。

src/androidTest/ ソースセット内のインストルメンテーション テストは、すべてのビルド バリアントで共有されます。アプリの「MyFlavor」バリアント用のテスト APK をビルドすると、Gradle は src/androidTest/ ソースセットと src/androidTestMyFlavor/ ソースセットを結合します。

Android Studio でビルド バリアントに応じたテスト ソースセットを追加する手順は次のとおりです。

  1. [Project] ウィンドウでメニューをクリックし、[Project] ビューを選択します。
  2. 該当するモジュール フォルダ内で src フォルダを右クリックし、[New] > [Directory] をクリックします。
  3. ディレクトリ名として「androidTestVariantName」と入力します。たとえばビルド バリアントの名前が「MyFlavor」である場合は、ディレクトリ名を「androidTestMyFlavor」にします。
  4. [OK] をクリックします。
  5. 新しいディレクトリを右クリックして、[New] > [Directory] を選択します。
  6. ディレクトリ名として「java」と入力し、[OK] をクリックします。

これで、新しいテストの追加手順に沿って、この新しいソースセットにテストを追加できるようになりました。[Choose Destination Directory] ダイアログが表示されたら、新たに作成したバリアント用テスト ソースセットを選択します。

アプリのコード ソースセットに対応するソースセットに、インストルメンテーション テストのファイルがどのように配置されるかの例を下表に示します。

表 1. アプリのソースコードと、対応するインストルメンテーション テストのファイル

アプリクラスのパス 対応するインストルメンテーション テストクラスのパス
src/main/java/Example.java src/androidTest/java/AndroidExampleTest.java
src/myFlavor/java/Example.java src/androidTestMyFlavor/java/AndroidExampleTest.java

アプリ ソースセットの場合と同様に、Gradle のビルドでは、異なるテスト ソースセットのファイルを統合し、オーバーライドします。この場合、androidTestMyFlavor ソースセット内の AndroidExampleTest.java ファイルは、androidTest ソースセット内のバージョンをオーバーライドします。これは、プロダクト フレーバーのソースセットがメインのソースセットよりも優先されるためです。

ビルド バリアント セレクタで異なるフレーバーを選択すると、該当する androidTest フォルダが Android ビューに表示され、使用するフォルダが表示されます。

MyFlavor バリアントが選択され、androidTestMyFlavor フォルダが Android ビューに表示されています
図 1. MyFlavor バリアントが選択され、androidTestMyFlavor フォルダが Android ビューに表示されています。

別のバリアントが選択されている場合、androidTestMyFlavor フォルダは表示されません。

OtherFlavor バリアントが選択され、androidTestMyFlavor フォルダが Android ビューに表示されていません
図 2. OtherFlavor バリアントが選択され、androidTestMyFlavor フォルダが Android ビューに表示されていません。

[Project] ビューを使用している場合は多少異なりますが、同じ原則が適用されます。

MyFlavor バリアントが選択され、androidTestMyFlavor フォルダが Project ビューでアクティブになっています
図 3. MyFlavor バリアントが選択され、androidTestMyFlavor フォルダが Project ビューでアクティブになっています。

別のバリアントが選択されている場合、androidTestMyFlavor フォルダは引き続き表示されますが、アクティブとしては表示されません。

OtherFlavor バリアントが選択され、androidTestMyFlavor フォルダが Project ビューでアクティブになっていません
図 4. OtherFlavor バリアントが選択され、androidTestMyFlavor フォルダが Project ビューでアクティブになっていません。

ソースセットがどのように統合されるかについては、ソースセットをご覧ください。

インストルメンテーション マニフェスト設定を構成する

インストルメンテーション テストは、独自の AndroidManifest.xml ファイルとともに個別の APK に組み込まれます。Gradle がテスト APK をビルドすると、自動的に AndroidManifest.xml ファイルが生成され、<instrumentation> ノードで構成されます。Gradle によってこのノードが構成されるのは、targetPackage プロパティがテスト対象アプリの正しいパッケージ名を指すようにするためでもあります。

このノードの他の設定を変更するには、次のコードサンプルに示すように、テスト ソースセットに別のマニフェスト ファイルを作成するか、モジュール レベルの build.gradle ファイルを構成します。オプションの一覧については、BaseFlavor API リファレンスをご覧ください。

Groovy

android {
    ...
    defaultConfig {
        ...
        testApplicationId "com.example.test"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testHandleProfiling true
        testFunctionalTest true
    }
}

Kotlin

android {
    ...
    defaultConfig {
        ...
        testApplicationId = "com.example.test"
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        testHandleProfiling = true
        testFunctionalTest = true
    }
}

Each product flavor you configure can override properties in the defaultConfig {} block. To learn more, go to Configure product flavors.

The properties in the snippet are:

Setting Description
testApplicationId Specifies the application ID for the test APK.
testInstrumentationRunner Specifies the fully qualified class name of the test instrumentation runner.
testHandleProfiling If set to true, enables the instrumentation class to start and stop profiling.
If set to false, profiling occurs the entire time the instrumentation class is running.
testFunctionalTest If set to true, indicates that the Android system should run the instrumentation class as a functional test.
The default value is false.

Change the test build type

By default, all instrumentation tests run against the debug build type. You can change this to another build type by using the testBuildType property in your module-level build.gradle file. For example, if you want to run your tests against your staging build type, edit the file as shown in the following snippet:

Groovy

android {
    ...
    testBuildType "staging"
}

Kotlin

android {
    ...
    testBuildType = "staging"
}

Gradle テスト オプションを構成する

Android Gradle プラグインを使用すると、テストの全部または一部に対して特定のオプションを指定できます。モジュール レベルの build.gradle ファイルで、testOptions ブロックを使用して、Gradle が実行するすべてのテストに適用されるオプションを指定します。

Groovy

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        reportDir "$rootDir/test-reports"
        resultsDir "$rootDir/test-results"
    }
}

Kotlin

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        reportDir "$rootDir/test-reports"
        resultsDir = "$rootDir/test-results"
    }
}

reportDir プロパティは、Gradle がテストレポートを保存するディレクトリを変更します。デフォルトでは、Gradle はテストレポートを path_to_your_project/module_name /build/outputs/reports/ ディレクトリに保存します。$rootDir は、現在のプロジェクトのルート ディレクトリへの相対パスを設定します。

resultsDir プロパティは、Gradle がテスト結果を保存するディレクトリを変更します。デフォルトでは、Gradle はテスト結果を path_to_your_project/module_name /build/outputs/test-results/ ディレクトリに保存します。$rootDir は、現在のプロジェクトのルート ディレクトリへの相対パスを設定します。

ローカル単体テストのみのオプションを指定するには、testOptions 内に unitTests ブロックを構成します。

Groovy

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            returnDefaultValues true

            all {
                jvmArgs '-XX:MaxPermSize=256m'

                if (it.name == 'testDebugUnitTest') {
                    systemProperty 'debug', 'true'
                }
                ...
            }
        }
    }
}

Kotlin

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            returnDefaultValues = true

            all {
                jvmArgs = listOf("-XX:MaxPermSize=256m")

                 if (it.name == "testDebugUnitTest") {
                    systemProperty = mapOf("debug" to "true")
                }
                ...
            }
        }
    }
}

デフォルトでは、テストするコードが Android プラットフォーム API にアクセスしようとすると、ローカル単体テストで例外がスローされます(Android の依存関係をモックする場合、または Mockito のようなテスト フレームワークを使用する場合を除きます)。ただし returnDefaultValues プロパティを有効にすると、プラットフォーム API にアクセスしたとき、テストで例外をスローされるのではなく null またはゼロが返されるようになります。

all ブロックは、Gradle がローカル単体テストを実行する方法を制御するためのオプションをカプセル化します。指定できるすべてのオプションの一覧については、Gradle のリファレンス ドキュメントをご覧ください。

jvmArgs プロパティは、テスト JVM の JVM 引数を設定します。

タスク名を確認して、指定したテストにのみオプションを適用することもできます。このスニペットの例では、testDebugUnitTest タスクに対してのみ、debug プロパティが true に設定されています。

インストルメンテーション テスト専用のテスト モジュールを使用する

インストルメンテーション テスト専用のモジュールが必要な場合、残りのコードをテストから分離するには、別のテスト モジュールを作成し、ライブラリ モジュールの場合と同様にビルドを構成します。

テスト モジュールを作成する手順は次のとおりです。

  1. ライブラリ モジュールを作成します。
  2. モジュール レベルの build.gradle ファイルで、com.android.library の代わりに com.android.test プラグインを適用します。
  3. プロジェクトの同期アイコン をクリックします。

テスト モジュールを作成したら、テストコードをメインまたはバリアントのソースセット(src/main/javasrc/variant/java など)に追加します。アプリ モジュールで複数のプロダクト フレーバーを定義している場合は、テスト モジュールにそれらのフレーバーを再作成できます。その場合、テスト モジュールはバリアント認識型の依存関係管理を使用して、ターゲット モジュール内の一致するフレーバーをテストしようとします。

デフォルトでは、デバッグ バリアントのみがテスト モジュールに含まれ、テストされます。ただし、テスト済みのアプリ プロジェクトに合わせて、新しいビルドタイプを作成できます。テスト モジュールでデバッグ以外のビルドタイプをテストするには、次に示すように、VariantFilter を使用してテスト プロジェクトのデバッグ バリアントを無効にします。

Groovy

android {
    variantFilter { variant ->
        if (variant.buildType.name.equals('debug')) {
            variant.setIgnore(true);
        }
    }
}

Kotlin

android {
    variantFilter {
        if (buildType.name == "debug") {
            ignore = true
        }
    }
}

テスト モジュールのターゲットをアプリの特定のフレーバーまたはビルドタイプのみにする場合は、matchingFallbacks プロパティを使用して、テストするバリアントのみをターゲットにできます。これにより、テスト モジュール自体でそれらのバリアントを構成する必要もなくなります。