EspressoによるUIテスト
Espressoで自動UIテストを記述します。onView()でViewを検索し、perform()で操作し、check()で状態を検証して、RecyclerViewの操作をテストします。
「EspressoによるUIテスト」はCoddyKit上の無料Android Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAndroid Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Android Academyコースには全4レッスンが含まれています。
Espressoとは何ですか?
EspressoはAndroid公式のUIテストフレームワークです。ボタンのタップ、テキストの入力、リストのスクロールなど、アプリのUIを操作し、画面に表示された内容をアサートするテストを記述できます。
Espressoはデバイスまたはエミュレーター上で実行されるインストルメンテーションテストです。UIスレッドとも自動的に同期するため、不安定なsleep()呼び出しは必要ありません。
セットアップ
EspressoはAndroidのテストツールキットに含まれています。次の依存関係をapp/build.gradleに追加します:
// app/build.gradle:
android {
defaultConfig {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}
dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1' // RecyclerView
}ActivityScenarioRule
ActivityScenarioRuleを使用すると、各テストの前にActivityを起動し、後で閉じることができます:
@RunWith(AndroidJUnit4::class)
class LoginActivityTest {
@get:Rule
val activityRule = ActivityScenarioRule(LoginActivity::class.java)
@Test
fun `login button is displayed`() {
onView(withId(R.id.btnLogin))
.check(matches(isDisplayed()))
}
}onView()とViewMatchers
onView(matcher)は、現在の階層からビューを検索します。複数のmatcherを組み合わせて、対象を正確に指定します:
// Match by ID:
onView(withId(R.id.tvTitle))
// Match by text:
onView(withText("Submit"))
// Match by content description (for accessibility):
onView(withContentDescription("Close dialog"))
// Combine matchers:
onView(allOf(withId(R.id.btnSave), isEnabled()))
// Inside a specific parent:
onView(withId(R.id.btnSave)).inRoot(isDialog())ViewActions — ビューの操作
ビューを見つけたら、.perform()でアクションを実行します:
// Tap a button:
onView(withId(R.id.btnLogin)).perform(click())
// Type into an EditText:
onView(withId(R.id.etEmail))
.perform(typeText("alice@example.com"), closeSoftKeyboard())
// Clear text and retype:
onView(withId(R.id.etPassword))
.perform(clearText(), typeText("secret123"), closeSoftKeyboard())
// Scroll to a view:
onView(withId(R.id.btnSubmit)).perform(scrollTo(), click())
// Long press:
onView(withId(R.id.ivImage)).perform(longClick())ViewAssertions — 状態の検証
.check()で画面に表示されている内容を確認します:
// View is displayed:
onView(withId(R.id.tvError)).check(matches(isDisplayed()))
// View has specific text:
onView(withId(R.id.tvTitle)).check(matches(withText("Welcome!")))
// View is not displayed (GONE or INVISIBLE):
onView(withId(R.id.progressBar)).check(matches(not(isDisplayed())))
// View is enabled:
onView(withId(R.id.btnSave)).check(matches(isEnabled()))
// View does not exist:
onView(withId(R.id.tvError)).check(doesNotExist())完全なログインテスト
認証情報を入力してログインをタップする一連のテストです:
@Test
fun `successful login shows home screen`() {
// Type email
onView(withId(R.id.etEmail))
.perform(typeText("alice@example.com"), closeSoftKeyboard())
// Type password
onView(withId(R.id.etPassword))
.perform(typeText("password123"), closeSoftKeyboard())
// Tap login button
onView(withId(R.id.btnLogin)).perform(click())
// Assert welcome message is shown
onView(withId(R.id.tvWelcome))
.check(matches(withText("Welcome, Alice!")))
}RecyclerViewのテスト
espresso-contribのRecyclerViewActionsを使用して、リスト項目を操作します:
import androidx.test.espresso.contrib.RecyclerViewActions
@Test
fun `clicking item opens detail screen`() {
// Scroll to position 5 and click:
onView(withId(R.id.recyclerView))
.perform(RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(
5, click()
))
// Assert detail screen is shown:
onView(withId(R.id.tvDetailTitle)).check(matches(isDisplayed()))
}入力検証のテスト
入力が無効な場合にエラーメッセージが表示されることを検証します:
@Test
fun `empty email shows error message`() {
// Leave email blank, tap login
onView(withId(R.id.btnLogin)).perform(click())
// Assert error is shown
onView(withId(R.id.tilEmail))
.check(matches(hasDescendant(withText("Email is required"))))
}
@Test
fun `short password shows error`() {
onView(withId(R.id.etPassword))
.perform(typeText("123"), closeSoftKeyboard())
onView(withId(R.id.btnLogin)).perform(click())
onView(withId(R.id.tilPassword))
.check(matches(hasDescendant(withText("Minimum 6 characters"))))
}Idling Resources
EspressoはUIスレッドがアイドル状態になるまで自動的に待機しますが、ネットワーク呼び出しやコルーチンは待機しません。IdlingResourceを使用して、非同期処理が完了するまでEspressoに待機させます:
// CountingIdlingResource: increment before async work, decrement when done
val idlingResource = CountingIdlingResource("NetworkCall")
// In your ViewModel/Repository:
idlingResource.increment()
viewModelScope.launch {
loadData()
idlingResource.decrement()
}
// In test setUp:
@Before
fun setUp() {
IdlingRegistry.getInstance().register(idlingResource)
}
@After
fun tearDown() {
IdlingRegistry.getInstance().unregister(idlingResource)
}Espressoテストの実行
接続されたデバイスまたはエミュレーターでインストルメンテーションテストを実行します:
- Android Studioの場合:テストクラスを右クリックして→「Run」を選択します
- ターミナルの場合:
./gradlew connectedAndroidTest - 結果は
app/build/reports/androidTests/に表示されます
安定した高速なテスト実行には、Android Emulator API 28以降を使用してください。不安定な結果を防ぐため、開発者向け設定でアニメーションを無効にします。
確認問題
ビューを検索してそのテキストを確認する、正しいEspressoのパターンはどれですか?
まとめ:EspressoによるUIテスト
自動UIテストにより、ユーザーが気づく前にデグレードを発見できます:
onView(matcher)— ビューを検索します.perform(action)— タップ、入力、スクロールを実行します.check(matches(...))— 表示状態、テキスト、状態をアサートします- リスト操作には
RecyclerViewActionsを使用します - 非同期処理には
IdlingResourceを使用します - 不安定なテストを防ぐため、システムアニメーションを無効にします
次は、プロのようにアプリをデバッグしてプロファイリングします。
よくある質問
「EspressoによるUIテスト」レッスンは無料ですか?
はい。「EspressoによるUIテスト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Android Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Android Academyコースには全4レッスンが含まれています。
「EspressoによるUIテスト」で何を学びますか?
Espressoで自動UIテストを記述します。onView()でViewを検索し、perform()で操作し、check()で状態を検証して、RecyclerViewの操作をテストします。 ブラウザで直接実行するハンズオンコードでAndroid Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Android Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAndroid Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「EspressoによるUIテスト」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAndroid Academyレッスンでコードを書いて実行できますか?
はい。すべてのAndroid Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- JUnitによるユニットテスト
- Mockitoによるモック
- EspressoによるUIテスト
- デバッグとプロファイリング