Robolectric 戦略

Robolectric は Google が管理するオープンソース フレームワークで、エミュレータのオーバーヘッドや不安定さなしに、JVM 内のシミュレートされた Android 環境でテストを実行できるものです。Lollipop(API レベル 21)以降のすべてのバージョンの Android をサポートしています。

多くの大規模なプロジェクトでは、Robolectric を使用してテストの速度と信頼性を高め、実際のデバイスやエミュレータでテストを実行する費用を削減しています。これには、Robolectric に大きく依存するほとんどの Google アプリが含まれます。

Robolectric はすべての機能と API をサポートしているわけではないため、エミュレータの完全な代替手段ではありません。たとえば、Robolectric にはエミュレータのような画面がなく、一部の API は部分的にしかサポートされていません。ただし、単体テストとほとんどの UI テストを信頼性を持って実行するのに十分な部分をエミュレートします。

テスト戦略

Robolectric で実施できるテスト戦略には、単体テストと UI テストの 2 種類があります。

単体テスト

Robolectric は、Android アプリで「単体テスト」を可能にする方法として考案されました。たとえば、アクティビティの起動をシミュレートし、その中のロジックをテストして、すべてのライフサイクル メソッドを呼び出すことができます。

Robolectric のフェイク(シャドウ)をユニットテストの依存関係として使用することもできます。たとえば、クラスが Bundle を使用する場合や、Bluetooth 接続を偽装する必要がある場合などです。

一般的に、テスト可能なアーキテクチャを実装する場合、コードは Android フレームワークに依存せず、単体テストで個別にテストできるため、単体テストに Robolectric を使用する必要はありません。

UI テスト

Robolectric は、Espresso テストや Compose テストなどの UI テストも実施できます。インストルメンテーション テストを Robolectric に変換するには、テストを test ソースセットに移動し、Robolectric の依存関係を設定します。

android {
  testOptions {
    unitTests {
      isIncludeAndroidResources = true
    }
  }
}

dependencies {
  testImplementation("junit:junit:4.13.2")
  testImplementation("org.robolectric:robolectric:4.13")
}

test ソースセットにある UI テストはすべて Robolectric で実行されます。

import androidx.test.espresso.Espresso.onView

@RunWith(AndroidJUnit4::class)
class AddContactActivityTest {
    @Test
    fun inputTextShouldBeRetainedAfterActivityRecreation() {
        // GIVEN
        val contactName = "Test User"
        val scenario = ActivityScenario.launchActivity<AddContactActivity>()

        // WHEN
        // Enter contact name
        onView(withId(R.id.contact_name_text))
            .perform(typeText(contactName))
        // Destroy and recreate Activity
        scenario.recreate()

        // THEN
        // Check contact name was preserved.
        onView(withId(R.id.contact_name_text))
            .check(matches(withText(contactName)))
     }
}

ほとんどの UI テストはフレームワークを操作しないため、Robolectric で実行できます。必要な忠実度が十分に高いため、Robolectric で動作テストを実行できます。たとえば、Compose テストで、ボタンのクリック後に UI が変更されたことを確認する場合などです。

Robolectric では、スクリーンショット テストなどの他の UI テストを実行できます。ただし、デバイスによって画面のレンダリングが若干異なるため、忠実度は低くなります。

Robolectric の実装が各ユースケースに適しているかどうかを判断する必要がありますが、推奨事項をいくつかご紹介します。

  • コンポーネント、機能、アプリのテストで UI の動作を分離してテストする場合は、Robolectric を使用します。一般に、これらのテストは UI の状態管理と動作をチェックし、外部依存関係を操作しません。
  • ピクセル精度が重要でない場合は、Robolectric を使用してスクリーンショットを撮影します。たとえば、コンポーネントがさまざまなフォントサイズやテーマにどのように反応するかをテストする場合です。

: Robolectric はネイティブでスクリーンショットを撮影できますが、スクリーンショット テストを実行するにはサードパーティ ライブラリが必要です。

Robolectric テストとデバイステスト

まとめると、Robolectric はほとんどの UI テストを実行するのに十分な忠実度を提供しますが、エッジツーエッジやピクチャー イン ピクチャーなどのシステム UI に関連するものや、WebView などのサポートされていない機能に依存している場合など、デバイステストが必要なケースもあります。