mcpField
R
running-instrumented-tests-with-androidjunit4

running-instrumented-tests-with-androidjunit4

github.com/skydovesテスト・品質33965 回インストール22 週間前に更新
リポジトリ

running-instrumented-tests-with-androidjunit4 について

AndroidJUnit4 によるインストルメンテーションテストの依存関係、Runner、アノテーション、ルールを扱うスキルガイドです。Android 開発者向けに、Test Orchestrator、実行引数、権限付与、アニメーション制御を含む起動・設定問題の解決方法をまとめています。

主な機能

  1. 01AndroidX Test の依存関係設定
  2. 02インストルメンテーション Runner の設定
  3. 03非推奨ではない AndroidJUnit4 の使用
  4. 04インストルメンテーション引数の取得
  5. 05Test Orchestrator の設定
  6. 06権限付与とアニメーション無効化

活用シーン

  1. 01インストルメンテーション Runner の検出失敗を修正
  2. 02Test Orchestrator でテストプロセスを分離
  3. 03アノテーションや引数でテストを絞り込む

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/skydoves/android-testing-skills --skill running-instrumented-tests-with-androidjunit4

インストール後、Claude Code で/running-instrumented-tests-with-androidjunit4を入力して読み込まれたか確認します。

詳細

AndroidJUnit4 でインストルメンテーションテストを実行する — ランナーのスタックを正しく設定する

ランナーのスタックが正しく設定されていないと、アサーションが実行される前にインストルメンテーションテストが失敗します。非推奨の AndroidJUnit4 インポート、androidTestUtil ではなく androidTestImplementation に設定されたオーケストレーター、androidx.test.platform.app.InstrumentationRegistry ではなく非推奨の androidx.test.InstrumentationRegistry などが原因です。このスキルでは、正確な依存関係マトリクス、ランナーの Gradle 設定、関連するアノテーションとルールを解説します。

このスキルを使用する場面

  • IDE が androidx.test.runner.AndroidJUnit4 に @Deprecated の警告を表示する、またはテストはコンパイルされるものの、非推奨の警告が出る場合。
  • am instrument が INSTRUMENTATION_FAILED: <pkg>/androidx.test.runner.AndroidJUnitRunner または Test runner not found を返す場合。
  • Gradle で Test Orchestrator を設定しているのに、テストが単一のインストルメンテーションプロセスを共有している場合(オーケストレーターが警告なしに無効化されています)。
  • ユーザーが am instrument 経由で -e size small / -e package com.foo を渡しても、テストがそれを無視する場合 — RunnerArgs が接続されていません。
  • テストで ACCESS_FINE_LOCATION / RECORD_AUDIO などが必要で、ユーザーが adb から手動で権限を付与している場合。
  • API 26 未満でテストをスキップしたくて、アノテーションを探している場合。

このスキルを使用しない場面

  • ユーザーが Activity を起動したり、ライフサイクルを操作したりする場合 — ../../scenarios/launching-activities-with-activityscenario/SKILL.md を参照してください。
  • ユーザーが View を操作する場合 — ../../espresso/writing-espresso-tests/SKILL.md を参照してください。
  • ユーザーがシステム UI や別のアプリを操作する場合 — ../../uiautomator/cross-app-tests-with-uiautomator/SKILL.md を参照してください。
  • ユーザーが JVM(Robolectric / 純粋な JUnit)テストを実行する場合 — ../../../jvm-tests/runner/configuring-junit4-on-android/SKILL.md を参照してください。
  • ユーザーが何をテストするかを検討している段階の場合 — ../../../fundamentals/strategies/applying-testing-strategies/SKILL.md を参照してください。

前提条件

  • Android Gradle Plugin モジュール(com.android.application または com.android.library)。
  • ディスク上に src/androidTest/ ソースセットがあること(./gradlew :module:connectedDebugAndroidTest が解決される必要があります)。
  • エミュレーターまたは実機(あるいは Firebase Test Lab / マネージドデバイス)— ランナーは JVM 上では実行できません。
  • テストのクラスパスに JUnit 4 が含まれていること(junit:junit:4.13.2)。JUnit 5 には Vintage エンジンブリッジが必要ですが、ここでは対象外です。

ワークフロー

  • 1. AndroidX Test のアーティファクトを androidTestImplementation に固定します。 これらは docs/CORPUS.md H.1 に記載された、2026 年時点の標準的な GA バージョンです。
dependencies {
    androidTestImplementation("androidx.test:core:1.7.0")
    androidTestImplementation("androidx.test:runner:1.7.0")
    androidTestImplementation("androidx.test:rules:1.7.0")
    androidTestImplementation("androidx.test.ext:junit:1.3.0")
    androidTestImplementation("androidx.test.ext:junit-ktx:1.3.0")
    androidTestImplementation("androidx.test.ext:truth:1.7.0")
}

androidx.test.ext:junit は、非推奨ではない AndroidJUnit4 ランナーと 非推奨ではない ActivityScenarioRule を提供するアーティファクトです。androidx.test:runner にも従来の AndroidJUnit4(非推奨)が含まれています — こちらからはインポートしないでください。tasks/research/R1-androidx-test-core.md の 481-490 行を参照してください。

  • 2. モジュールの android.defaultConfig で testInstrumentationRunner を設定します。 ランナーの FQCN は androidx.test.runner.AndroidJUnitRunner です — これはランナーの クラス であり、非推奨の AndroidJUnit4 テストランナーアノテーション とは異なることに注意してください。tasks/research/R1-androidx-test-core.md の 270-289 行より。
android {
    defaultConfig {
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        // Optional: pass `-e key value` args to every run via Gradle
        testInstrumentationRunnerArguments["clearPackageData"] = "true"
    }
    testOptions {
        animationsDisabled = true                  // hermetic — see Pattern below
    }
}
  • 3. androidx.test.ext.junit.runners の @RunWith(AndroidJUnit4::class) でテストクラスにアノテーションを付けます。 正しいインポートはこれだけです。
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class LoginActivityTest {
    @Test fun loginSucceeds() { /* ... */ }
}

非推奨の androidx.test.runner.AndroidJUnit4 は、runner-1.7.0/androidx/test/runner/AndroidJUnit4.java:43-44 で @Deprecated として宣言されています。実行時には引き続き動作しますが、IDE が警告を表示し、コードモッドによる置き換えの対象になります。

  • 4. androidx.test.platform.app.InstrumentationRegistry を使ってインストルメンテーション引数を読み取ります。 従来の androidx.test.InstrumentationRegistry(platform.app を含まないもの)は @Deprecated および @InlineMe として宣言され、標準クラスへの移行が促されています — tasks/research/R1-androidx-test-core.md の 142-153 行を参照してください。
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.core.app.ApplicationProvider

val instrumentation = InstrumentationRegistry.getInstrumentation()
val args: Bundle = InstrumentationRegistry.getArguments()       // -e key value extras
val targetContext: Context = ApplicationProvider.getApplicationContext()
val testContext: Context = instrumentation.context             // package context of the test APK

InstrumentationRegistry.getArguments() は、am instrument -e key value で渡された -e のキーと値のペアを公開します。例:-e size small -e numShards 4。サポート対象キーの正式な一覧は、runner-1.7.0/androidx/test/internal/runner/RunnerArgs.java の54~99行目にあります(tasks/research/R1-androidx-test-core.md の295~336行目を参照)。

  • 5. androidx.test.filters の @SmallTest / @MediumTest / @LargeTest を使ってテストにアノテーションを付けます。 am instrument -e size small と組み合わせることで、実行時間の範囲でフィルタリングできます。パッケージのKDocによると、SmallTest は200ms以下、MediumTest は1000ms以下、LargeTest は1000ms超です。同じパッケージにあるアノテーション:@FlakyTest、@RequiresDevice、@Suppress。
import androidx.test.filters.SmallTest
import androidx.test.filters.SdkSuppress

@RunWith(AndroidJUnit4::class)
@SmallTest
class LoginViewModelTest { /* ... */ }

@Test
@SdkSuppress(minSdkVersion = 26)
fun usesApi26OnlyApi() { /* ... */ }

@SdkSuppress(minSdkVersion, maxSdkVersion, excludedSdks, codeName) は runner-1.7.0/androidx/test/filters/SdkSuppress.java:39-58 にあります。API範囲外のテストは失敗ではなく、スキップ(仮定の失敗、終了コード -4)になります。

  • 6. Test Orchestrator は androidTestImplementation ではなく、androidTestUtil に追加します。 これはランナーの設定で最もよくある単独の設定ミスです。Test Orchestrator は各 @Test を専用のインストルメンテーションプロセスで実行するため、クラッシュの影響がそのテストだけに限定されます。テスト間で clearPackageData を実行することもできます。
dependencies {
    androidTestUtil("androidx.test:orchestrator:1.6.1")  // installs orchestrator APK on device
    androidTestUtil("androidx.test:services:1.6.0")      // required for clearPackageData
}

android {
    testOptions {
        execution = "ANDROIDX_TEST_ORCHESTRATOR"
    }
    defaultConfig {
        testInstrumentationRunnerArguments["clearPackageData"] = "true"
    }
}

androidTestUtil は、テスト実行前にデバイスへヘルパーAPKをインストールする、AGPの特別な構成です。Orchestratorを androidTestImplementation に指定してもコンパイルは通りますが、何も起きず、テストは引き続き単一の共有プロセスで実行されます。tasks/research/R1-androidx-test-core.md の683~687行目を参照してください。

  • 7. adb shell pm grant の代わりに GrantPermissionRule.grant(...) を使って実行時権限を付与します。 このルールは androidx.test:rules に含まれており、テストクラスの実行中に権限を付与します。
import androidx.test.rule.GrantPermissionRule
import org.junit.Rule

@get:Rule
val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(
    android.Manifest.permission.ACCESS_FINE_LOCATION,
    android.Manifest.permission.RECORD_AUDIO,
)

このルールは rules-1.7.0/androidx/test/rule/GrantPermissionRule.java に実装されています。API 23以降では UiAutomation.grantRuntimePermission を使用します。古いデバイスでは、権限をマニフェストですでに付与しておく必要があります(このルールは何もしません)。

  • 8. 再現性の高いテスト実行ではアニメーションを無効にします。 testOptions { animationsDisabled = true } を指定すると、テスト実行中は window_animation_scale、transition_animation_scale、animator_duration_scale が 0 に設定され、終了処理時に以前の値へ戻されます。これを設定しないと、タップによるフォーカス、リップル、Activityの遷移とアサーションが競合します。

  • 9. 複数の @Rule の順序を @Rule(order = N) で指定します(任意)。 順序の値が小さいほど、外側で評価されます。Hiltでは @HiltAndroidRule を order = 0 にする必要があります。

@get:Rule(order = 0) val hiltRule = HiltAndroidRule(this)
@get:Rule(order = 1) val activityRule = ActivityScenarioRule(LoginActivity::class.java)
  • 10. 実行します。 ホストから次のコマンドを実行します。
./gradlew :app:connectedDebugAndroidTest
# or via adb directly:
adb shell am instrument -w -r \
  -e size small \
  -e clearPackageData true \
  com.example.app.test/androidx.test.runner.AndroidJUnitRunner

終了コードを正しく取得するには、-w(待機)が必須です。これがないと、テストが失敗しても $? は 0 になります。docs/CORPUS.md のI.5を参照してください。

パターン

パターン:誤りと正しい例 — AndroidJUnit4 のインポート
// WRONG
import androidx.test.runner.AndroidJUnit4   // @Deprecated since androidx.test:runner 1.x
@RunWith(AndroidJUnit4::class)
class FooTest
// WRONG because: this class is @Deprecated at runner-1.7.0/.../AndroidJUnit4.java:43-44.
// The IDE flags it; codemods replace it; the doc explicitly redirects to ext.junit.
// RIGHT
import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class)
class FooTest
パターン:誤りと正しい例 — InstrumentationRegistry のインポート
// WRONG
import androidx.test.InstrumentationRegistry             // @Deprecated, every member @InlineMe'd
val ctx = InstrumentationRegistry.getTargetContext()     // returns target package context, NOT the application
// WRONG because: monitor-1.8.0/androidx/test/InstrumentationRegistry.java:34 is @Deprecated.
// Use androidx.test.platform.app.InstrumentationRegistry + ApplicationProvider.
// RIGHT
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.core.app.ApplicationProvider
val instrumentation = InstrumentationRegistry.getInstrumentation()
val ctx: Context = ApplicationProvider.getApplicationContext()
パターン:誤りと正しい例 — Test Orchestrator の設定(最もよくある設定ミス)
// WRONG
dependencies {
    androidTestImplementation("androidx.test:orchestrator:1.6.1")
}
android.testOptions.execution = "ANDROIDX_TEST_ORCHESTRATOR"
// WRONG because: orchestrator must be installed as a separate APK on the device.
// `androidTestImplementation` puts it on the test APK classpath instead, where it does
// nothing. Tests still run in one shared process. No error, just silent inactivation.
// RIGHT
dependencies {
    androidTestUtil("androidx.test:orchestrator:1.6.1")
    androidTestUtil("androidx.test:services:1.6.0")  // required for clearPackageData
}
android.testOptions.execution = "ANDROIDX_TEST_ORCHESTRATOR"
パターン:RunnerArgs を使った実行時のテストフィルタリング
# Run a single method
adb shell am instrument -w -r \
  -e class com.example.LoginActivityTest#loginSucceeds \
  com.example.app.test/androidx.test.runner.AndroidJUnitRunner

# Filter by size annotation
adb shell am instrument -w -r -e size small  com.example.app.test/androidx.test.runner.AndroidJUnitRunner

# Shard across N runners (CI fan-out)
adb shell am instrument -w -r -e numShards 4 -e shardIndex 0 \
  com.example.app.test/androidx.test.runner.AndroidJUnitRunner

サポート対象の -e キーの一覧は、runner-1.7.0/androidx/test/internal/runner/RunnerArgs.java:54-99 にあります(class、package、notClass、size、annotation、notAnnotation、numShards、shardIndex、clearPackageData、coverage、debug、listener など)。テスト内でこれらを取得するには、InstrumentationRegistry.getArguments() を読み取ります。

必須ルール

  • 必須: @RunWith(...) には androidx.test.ext.junit.runners.AndroidJUnit4 を使用してください。androidx.test.runner.AndroidJUnit4 形式は @Deprecated です。
  • 必須: androidx.test.platform.app.InstrumentationRegistry を使用してください。androidx.test.InstrumentationRegistry は @Deprecated です。
  • 必須: androidx.test:orchestrator は androidTestUtil に指定し、androidTestImplementation には指定しないでください。誤った構成に指定しても、エラーが出ずに失敗します。
  • 必須: testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" を設定してください(ランナーの クラス は非推奨ではありません。非推奨なのはテストランナーの アノテーション のみです)。
  • 必須: am instrument に -w を渡し、終了コードにテスト結果が反映されるようにしてください。これを付けない場合、$? は意味を持ちません。
  • 禁止: インストルメンテーションのライフサイクル(onCreate、onStart)を待つために Thread.sleep を呼び出さないでください。ActivityScenario.moveToState(../../scenarios/launching-activities-with-activityscenario/SKILL.md を参照)または IdlingResource を使用してください。
  • 禁止: テスト内から adb shell pm grant を使って権限を付与しないでください。テストクラスの範囲内で権限を付与し、適切に元に戻すために、GrantPermissionRule.grant(...) を使用してください。
  • 禁止: @Rule public ActivityTestRule を使用しないでください。これは @Deprecated です。@get:Rule val rule = ActivityScenarioRule(...) を使用してください。
  • 推奨: CI のシャードでサイズによるフィルタリングができるよう、すべてのインストルメンテーションテストクラスに @SmallTest、@MediumTest、または @LargeTest を付けてください。
  • 推奨: 個々のテストでは不要に見える場合でも、testOptions.animationsDisabled = true を設定してください。リップルやトランジションの不安定さは、気付かないうちに無関係なテストを破損させます。

検証

  • ./gradlew :<module>:connectedDebugAndroidTest の実行時に、Test runner not found や INSTRUMENTATION_FAILED が発生しない。
  • ソースファイルに androidx.test.runner.AndroidJUnit4 または androidx.test.InstrumentationRegistry(旧パス)のインポートがない。
  • grep -r "androidTestImplementation.*orchestrator" build.gradle* の結果が空である。orchestrator は androidTestUtil に指定します。
  • adb shell am instrument -w -r -e size small <pkg>.test/androidx.test.runner.AndroidJUnitRunner は、テスト失敗時にゼロ以外の終了コードを返す。
  • orchestrator が有効な場合、adb logcat | grep AndroidTestOrchestrator にテストごとのプロセス起動が表示される。
  • モジュールの android ブロックで testOptions.animationsDisabled = true が設定されている。
  • テストに必要なランタイム権限には、手動の adb shell pm grant ではなく、@get:Rule val rule = GrantPermissionRule.grant(...) が設定されている。

参考資料

  • Android Developers — AndroidJUnitRunner の概要:https://developer.android.com/training/testing/instrumented-tests/androidx-test-libraries/runner
  • Android Developers — Test Orchestrator:https://developer.android.com/training/testing/instrumented-tests/androidx-test-libraries/runner#use-android
  • AndroidX Test のリリースノート:https://developer.android.com/jetpack/androidx/releases/test
  • runner-1.7.0/androidx/test/runner/AndroidJUnit4.java の41~44行目 — @Deprecated public final class AndroidJUnit4 extends Runner。
  • junit-1.3.0/androidx/test/ext/junit/runners/AndroidJUnit4.java の49行目 — 現在の非推奨ではないランナー。JVM 上では Robolectric に、デバイス上では AndroidJUnit4ClassRunner に処理を委譲します。
  • runner-1.7.0/androidx/test/runner/AndroidJUnitRunner.java の270~372行目 — am instrument が呼び出すランナークラス。ライフサイクルと Orchestrator の待機ロジックが記載されています。
  • runner-1.7.0/androidx/test/internal/runner/RunnerArgs.java の54~99行目 — ランナーが受け付けるすべての -e キーの正式な一覧です。
  • monitor-1.8.0/androidx/test/InstrumentationRegistry.java の34行目 — @Deprecated の旧レジストリ。すべてのメンバーに、platform.app 形式への @InlineMe が付与されています。
  • monitor-1.8.0/androidx/test/platform/app/InstrumentationRegistry.java — 現在の正式なレジストリです。
  • rules-1.7.0/androidx/test/rule/GrantPermissionRule.java の1~100行目 — static GrantPermissionRule grant(String...)。
  • runner-1.7.0/androidx/test/filters/SdkSuppress.java の39~58行目 — minSdkVersion/maxSdkVersion/excludedSdks/codeName。
  • tasks/research/R1-androidx-test-core.md — ランナーとテストコアの詳細な解説(ランナーについては269~740行目、2種類の AndroidJUnit4 の混同については481~490行目)。
  • docs/CORPUS.md の Section H — インストルメンテーションライブラリの座標と非推奨化の表。
  • 関連スキル:../../managed-devices/running-tests-on-gradle-managed-devices/SKILL.md — Gradle が用意して起動・終了するエミュレーターでこれらのテストを実行します(CI で再現可能です)。
  • 関連セット:../../../adb/tests/running-instrumented-tests-via-adb/SKILL.md — adb shell am instrument -w -r でランナーを直接呼び出します。
  • 関連セット:../../../platform/legacy/migrating-from-android-test-classes/SKILL.md — モジュールが引き続き旧 android.test.* クラスまたは InstrumentationTestRunner を使用している場合は、まずこのランナースタックに移行してください。

コメント