Espressoは、Googleチームが開発しAndroidX Testの一部として提供される、Androidアプリケーションの自動化UIテストフレームワークです。孤立したコンポーネントをチェックするインストルメントテストとは異なり、Espressoは実際のUIと対話します:ボタンをクリックし、テキストを入力し、要素の表示を確認します。Google Android Developersによると、EspressoはUIスレッドとの自動同期を提供し、手動のThread.sleep()を不要にします。
重要ポイント
Espressoは、Android向けの自動化UIテストを作成するためのライブラリで、Google AndroidX Testの一部です。画面上のView要素を見つけ、それらに対して操作(クリック、入力、スワイプ)を実行し、その状態(表示、テキスト含有、有効)を検証するためのAPIを提供します。
Espressoの主要な機能は、アプリケーションのメインスレッドとの自動同期です。フレームワークは、次のチェックを実行する前に、すべての非同期タスク(coroutine、AsyncTask、Handler)が完了するのを待機します。これにより、競合状態による不安定なテストが排除され、UIテストが安定して信頼できるものになります — どのテストもThread.sleep()や待機ループを含みません。
Espressoは三本足の犬の原則に従います — テストは3つのステップで構成されます:要素を見つける(ViewMatcher)、操作を実行する(ViewAction)、結果を検証する(ViewAssertion)。3つのステップはすべてonView().perform().check()という呼び出しチェーンで記述されます。この概念により、テストは予測可能で読みやすくなります — 各テストは何を探し、何を実行し、何を検証するかを明示的に記述します。
アーキテクチャ Espressoは3つのコンポーネントに基づいています:Espresso(エントリーポイント — 静的メソッドonViewとonData)、ViewMatchers(要素検索)、ViewActions(操作)、ViewAssertions(検証)。内部的には、フレームワークはUIスレッドとの同期にIdling Resourceを使用します。
最も単純なテストは、IDでボタンを見つけ、クリックを実行し、テキスト「完了」が表示されることを確認します。すべての操作はテストの観点から同期的です — Espressoは、テストが続行される前にUIスレッドがイベントの処理を完了したことを保証します。これは組み込みの待機メカニズムによって実現されます:onViewはUIがアイドル状態になるまでテストの実行をブロックします。
@Test
fun buttonClick_showsSuccessText() {
// IDでボタンを見つけてクリック
onView(withId(R.id.button_submit))
.perform(click())
// テキスト「完了」が表示されることを確認
onView(withText("完了"))
.check(matches(isDisplayed()))
}
Espressoテストを起動するには、ActivityScenario(AndroidX Test)が使用され、特定の状態(実行中、一時停止、破棄)でActivityを作成します。ActivityScenarioを使用すると、純粋なUIテストに加えてActivityのライフサイクルをテストできます。たとえば、画面回転(Activityの再作成)時にデータが保持され、破棄後に復元されることを確認できます。
ViewMatchersは、Espresso.onViewクラスのメソッドセットで、リソースID(R.id)、テキスト、ヒント、親要素、階層などのさまざまな基準で画面上のViewsを見つけることができます。1つのマッチャーで一意の結果が得られない場合は、allOf()を使用してマッチャーを組み合わせることができます。
| マッチャー | 目的 |
|---|---|
| withId(R.id.name) | リソースIDで検索 |
| withText(「テキスト」) | 表示テキストで検索 |
| withHint(「ヒント」) | EditTextのヒント属性で検索 |
| isDisplayed() | 要素が画面に表示されているか確認 |
| hasSibling(matcher) | 兄弟要素で検索 |
| allOf(m1, m2) | 複数マッチャーの組み合わせ |
画面上に複数の同一要素がある場合(異なるテキストの2つのTextViewなど)、allOfを使用してマッチャーを組み合わせると便利です:onView(allOf(withId(R.id.title), withText(「こんにちは」)))。これにより、単一の要素の選択が保証されます。逆演算子 — not() — は要素を検索から除外し、hasSibling()は既知の要素の隣にある要素を見つけます。
ViewActionsは、Espressoが見つけたViewに対して実行する操作です:click()、typeText()、clearText()、scrollTo()、swipeLeft()など。操作はperform()メソッドに渡され、複数の操作を順次受け付けることができます。
perform()メソッドはvararg ViewActionを受け入れ、1つの要素に対する一連の操作を実行できます:フィールドをクリアし、新しいテキストを入力し、キーボードを閉じ、ボタンをクリックします。すべての操作はリストされた順序で実行され、Espressoは前の操作が完了してから次の操作が開始されることを保証します。
// EditTextにテキストを入力してボタンをクリック
onView(withId(R.id.edit_email))
.perform(
clearText(),
typeText("user@example.com"),
closeSoftKeyboard()
)
onView(withId(R.id.button_login))
.perform(click())
AdapterView(ListView、RecyclerView)内の要素には、onViewの代わりにonData()メソッドが使用されます。これはViewsではなくアダプターデータを操作します — モデルコンテンツで要素を見つけ、以降の操作に対応するViewを返します。onDataは、モデルデータフィールドで要素を特定するためにhamcrestマッチャーを使用します。
ViewAssertionsは、Viewが特定の状態にあることを検証します。基本的なメソッド — matches(matcher) — は、要素が指定されたマッチャーと一致するかを確認します。さらに、EspressoはdoesNotExist()(要素が存在しない)とselectedDescendantsMatch()(ネストされた要素の確認)を提供します。
UIテストで最も頻繁な確認:要素が表示されている(isDisplayed)、要素が特定のテキストを含む(withText)、要素が有効(isEnabled)、要素が選択されていない(isNotChecked)。各確認は失敗時に詳細な例外をスローします — 画面上のView階層を含みます。これによりデバッグが簡素化されます:エラーメッセージは確認時に実際に画面上にあった要素を示します。
標準の確認が不十分な場合は、ViewAssertionインターフェースを通じてカスタムの確認を作成できます。カスタムアサーションはViewを受け取り、プログラムでその状態を確認できます — たとえば、テキストの色、パディング、または標準マッチャーで公開されていないカスタムコンポーネントの状態など。
// 確認:TextViewが表示されテキストを含む
onView(withId(R.id.text_welcome))
.check(matches(isDisplayed()))
.check(matches(withText("ようこそ")))
// 確認:要素が表示されていない
onView(withId(R.id.progress_bar))
.check(doesNotExist())
Idling Resourceは、非同期処理とテストを同期するためのEspressoのメカニズムです。デフォルトでは、EspressoはHandler、AsyncTask、coroutine(coroutinesIdlingResource経由)を待機します。アプリケーションがカスタムスレッドやコールバックサービスを通じてバックグラウンド処理を行う場合は、カスタムIdling Resourceを登録する必要があります。
AndroidX Test 1.4.0以降、EspressoはCoroutinesIdlingResourceを介してcoroutineをサポートします。テストはUI確認を実行する前に、起動されたすべてのcoroutineが完了するのを自動的に待機します。より複雑なシナリオでは、CountingIdlingResourceが使用されます — タスク開始時にインクリメントされ、完了時にデクリメントされるカウンターです。
// OkHttp用のIdlingResourceを登録
class OkHttpIdlingResource(
private val client: OkHttpClient
) : IdlingResource {
private var isIdle = true
private var watcher: IdlingResource.ResourceCallback? = null
override fun getName() = "OkHttp"
override fun isIdleNow() = isIdle
override fun registerIdleTransitionCallback(
callback: IdlingResource.ResourceCallback
) {
watcher = callback
}
}
接続 EspressoをAndroidプロジェクトに追加するには、モジュールレベルのbuild.gradleに依存関係を追加します。EspressoはAndroidX Testの一部であるため、Espressoコア、拡張機能、JUnit統合の依存関係を指定するだけで十分です。テストはsrc/androidTestディレクトリに配置され、AndroidJUnitRunnerを介して物理デバイスまたはエミュレーターで実行されます。
最小限の依存関係セットには、espresso-core(コア)、espresso-contrib(RecyclerView、Drawer、Picker用の追加マッチャー)、runner(AndroidXテストランナー)が含まれます。すべてのテストはAndroid Test Orchestratorを介してエミュレーターまたは物理デバイスで実行されます。
// build.gradle.kts(androidTest依存関係)
android {
defaultConfig {
testInstrumentationRunner =
"androidx.test.runner.AndroidJUnitRunner"
}
}
dependencies {
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
androidTestImplementation("androidx.test.espresso:espresso-contrib:3.6.1")
androidTestImplementation("androidx.test:runner:1.6.1")
androidTestImplementation("androidx.test:rules:1.6.1")
}
Espressoテストは、Google Android Test Orchestratorを介して実行できます。これにより、各テストが個別のプロセスに分離され、実行間で状態がクリアされます。これにより、以前のテストの残留データによる不安定なテストが排除され、CIサーバーでの安定性が向上します。並列実行には、shardingが使用されます — 複数のエミュレーター間でのテスト分散。
よくある質問
Espressoはアプリケーションプロセス内で動作し、UIスレッドとの自動同期を使用します。UI Automatorはシステムレベルで動作し、他のアプリケーションと対話できますが、手動の待機管理が必要です。
これはGoogleのプレゼンテーションからの比喩です:Espressoテストは3本の柱 — ViewMatcher(検索)、ViewAction(操作)、ViewAssertion(検証)— の上に成り立っています。どれか1つを取り除くと、三本足の犬のようにテストは不安定になります。
RecyclerViewには、espresso-contribライブラリとonView(withId(R.id.recycler)).perform(actionOnItemAtPosition(0, click()))などのメソッドを使用します。代替として、AdapterView用のonData()や、RecyclerView内のテキストで要素を見つけるカスタムViewActionがあります。さらに、espresso-contribのRecyclerViewActionsを使用して、要素までスクロールして操作を実行できます。
フレーキーテストとは、コードの変更なしに、競合状態や非同期性のために時々失敗するテストです。EspressoはIdling Resourceを使用してこの問題を解決します — 確認を実行する前にすべてのバックグラウンドタスクが完了するのを待機します。
Espresso自体はスクリーンショットテスト用に設計されていませんが、ShotやPaparazziなどのライブラリと組み合わせることができます。EspressoがUIを目的の状態に準備し、比較ライブラリがスクリーンショットを撮って参照画像と比較します。このアプローチは視覚回帰テストと呼ばれ、インターフェースの予期しない変更を見つけるのに役立ちます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。