Espresso — ano ito, mga prinsipyo ng paggana at kung paano gamitin

May-akda: IT Sectr Nai-publish: 2026-04-08 Oras ng pagbabasa: 8 min

Ang Espresso ay isang framework para sa automated UI testing ng Android applications, na binuo ng Google team at bahagi ng AndroidX Test. Hindi tulad ng instrumental tests na sumusuri sa mga isolated component, ang Espresso ay nakikipag-ugnayan sa totoong UI: pumipindot ng mga button, naglalagay ng text, sumusuri sa pagpapakita ng mga elemento. Ayon sa Google Android Developers, ang Espresso ay nagbibigay ng awtomatikong synchronisasyon sa UI thread, na nag-aalis ng pangangailangan para sa manual na Thread.sleep().

Mga Pangunahing Punto

  • Espresso — Android UI testing framework na may awtomatikong thread synchronisasyon.
  • ViewMatcher — paghahanap ng View element sa screen ayon sa ID, text, parent hierarchy.
  • ViewAction — aksyon sa elemento: pag-click, paglagay ng text, pag-swipe.
  • ViewAssertion — pagsusuri ng estado ng elemento: ipinapakita, naglalaman ng text, aktibo.
  • Idling Resource — mekanismo ng paghihintay para sa pagkumpleto ng asynchronous operations bago ang UI check.

Ano ang Espresso?

Espresso ay isang library para sa pagsulat ng automated UI tests para sa Android, na bahagi ng Google AndroidX Test. Nagbibigay ito ng API para sa paghahanap ng View elements sa screen, pagsasagawa ng mga aksyon sa kanila (pag-click, pag-input, pag-swipe) at pagsusuri ng kanilang estado (ipinapakita, naglalaman ng text, aktibo).

Ang pangunahing tampok ng Espresso ay awtomatikong synchronisasyon sa pangunahing thread ng application. Ang framework ay naghihintay para sa pagkumpleto ng lahat ng asynchronous tasks (coroutines, AsyncTask, Handler) bago isagawa ang susunod na pagsusuri. Ito ay nag-aalis ng flaky tests na nauugnay sa race condition at ginagawang matatag at maaasahan ang UI tests — walang test na naglalaman ng Thread.sleep() o wait loops.

Ang Espresso ay sumusunod sa prinsipyo ng Three-Legged Dog — ang test ay binubuo ng tatlong hakbang: hanapin ang elemento (ViewMatcher), gawin ang aksyon (ViewAction), suriin ang resulta (ViewAssertion). Lahat ng tatlong hakbang ay isinusulat sa chain ng tawag na onView().perform().check(). Ang konseptong ito ay ginagawang predictable at madaling basahin ang mga test — bawat test ay malinaw na naglalarawan kung ano ang hinahanap, kung ano ang ginagawa, at kung ano ang sinusuri.

Paano gumagana ang Espresso

Arkitektura ng Espresso ay batay sa tatlong component: Espresso (entry point — static methods na onView at onData), ViewMatchers (paghahanap ng elements), ViewActions(aksyon) at ViewAssertions (pagsusuri). Sa loob, ang framework ay gumagamit ng Idling Resource para sa synchronisasyon sa UI thread.

Basic Espresso Test

Ang pinakasimpleng test ay naghahanap ng button ayon sa ID, nagsasagawa ng click, at sinusuri kung lumitaw ang text na “Tapos”. Lahat ng operasyon ay isinasagawa nang sabay-sabay mula sa pananaw ng test — ginagarantiyahan ng Espresso na natapos ng UI thread ang pagproseso ng event bago magpatuloy ang test. Ito ay nakakamit sa pamamagitan ng built-in na mekanismo ng paghihintay: hinaharangan ng onView ang pagpapatupad ng test hanggang sa maging stable ang UI.

kotlin
@Test
fun buttonClick_showsSuccessText() {
    // Hanapin ang button ayon sa ID at i-click
    onView(withId(R.id.button_submit))
        .perform(click())

    // Suriin na ang text na “Tapos” ay ipinapakita
    onView(withText("Tapos"))
        .check(matches(isDisplayed()))
}

ActivityScenario Rule

Para sa pagpapatakbo ng Espresso test, ginagamit ang ActivityScenario (AndroidX Test) na gumagawa ng Activity sa nais na estado — tumatakbo, naka-pause, nawasak. Ang ActivityScenario ay nagbibigay-daan sa pagtest ng lifecycle ng Activity bilang karagdagan sa purong UI. Halimbawa, maaaring suriin na ang data ay nai-save sa pag-ikot ng screen (recreation ng Activity) at na-restore pagkatapos ng pagkawasak.

ViewMatchers ay isang set ng mga method mula sa klase na Espresso.onView na nagpapahintulot na makahanap ng View sa screen ayon sa iba’t ibang criteria: resource identifier (R.id), text, hint, parent element at hierarchy. Kung ang isang matcher ay hindi nagbibigay ng natatanging resulta, ang mga matcher ay pinagsama sa pamamagitan ng allOf().

MatcherLayunin
withId(R.id.name)Paghahanap ayon sa resource ID
withText(“text”)Paghahanap ayon sa ipinapakitang text
withHint(“hint”)Paghahanap ayon sa hint attribute ng EditText
isDisplayed()Pagsusuri kung ang elemento ay nakikita sa screen
hasSibling(matcher)Paghahanap ayon sa katabing elemento
allOf(m1, m2)Kumbinasyon ng maraming matcher

Kombinasyon ng mga matcher

Kung mayroong maraming magkaparehong elemento sa screen (halimbawa, dalawang TextView na may magkaibang text), madaling pagsamahin ang mga matcher sa pamamagitan ng allOf: onView(allOf(withId(R.id.title), withText(“Hello”))). Ito ay ginagarantiyahan ang pagpili ng nag-iisang elemento. Ang kabaligtaran na operator — not() — ay nagbubukod ng mga elemento mula sa paghahanap, at ang hasSibling() ay naghahanap ng elemento sa tabi ng kilalang elemento.

ViewActions: pakikipag-ugnayan sa UI

ViewActions ay mga aksyon na ginagawa ng Espresso sa natagpuang View: click(), typeText(), clearText(), scrollTo(), swipeLeft() at iba pa. Ang mga aksyon ay ipinapasa sa method na perform() na maaaring tumanggap ng maraming aksyon nang sunud-sunod.

Chain ng mga Aksyon

Ang method na perform() ay tumatanggap ng vararg ViewAction, na nagpapahintulot na magsagawa ng sunod-sunod na mga aksyon sa isang elemento: linisin ang field, maglagay ng bagong text, isara ang keyboard at pindutin ang button. Lahat ng aksyon ay isinasagawa sa pagkakasunod-sunod na binanggit, at ginagarantiyahan ng Espresso na ang naunang aksyon ay natapos bago magsimula ang susunod.

kotlin
// Paglagay ng text sa EditText at pagpindot ng button
onView(withId(R.id.edit_email))
    .perform(
        clearText(),
        typeText("user@example.com"),
        closeSoftKeyboard()
    )

onView(withId(R.id.button_login))
    .perform(click())

Pagsusuri sa pamamagitan ng onData

Para sa mga elemento sa loob ng AdapterView (ListView, RecyclerView), ginagamit ang method na onData() sa halip na onView. Ito ay gumagana sa data ng adapter, hindi sa View — hinahanap ang elemento ayon sa nilalaman ng modelo at ibinabalik ang kaukulang View para sa mga susunod na aksyon. Ang onData ay gumagamit ng hamcrest matchers para hanapin ang elemento ayon sa mga field ng data model.

ViewAssertions: pagsusuri ng estado

ViewAssertions ay sumusuri kung ang View ay nasa isang partikular na estado. Ang basic method — matches(matcher) — ay sumusuri kung ang elemento ay tumutugma sa ibinigay na matcher. Dagdag pa, nag-aalok ang Espresso ng doesNotExist() (wala ang elemento) at selectedDescendantsMatch() (pagsusuri ng nested elements).

Mga Karaniwang Pagsusuri

Ang pinakakaraniwang pagsusuri sa UI tests: elemento ay ipinapakita (isDisplayed), elemento ay naglalaman ng partikular na text (withText), elemento ay aktibo (isEnabled), elemento ay hindi napili (isNotChecked). Bawat pagsusuri ay nagtatapon ng detalyadong exception kung nabigo — na may pagbanggit ng View hierarchy sa screen. Ito ay nagpapasimple ng debugging: sa mensahe ng error ay makikita kung aling mga elemento ang aktwal na nasa screen sa oras ng pagsusuri.

Custom na ViewAssertions

Kung hindi sapat ang standard na pagsusuri, maaaring gumawa ng sarili sa pamamagitan ng interface na ViewAssertion. Ang custom na assertion ay tumatanggap ng View at maaaring suriin ang estado nito nang programmatically — halimbawa, kulay ng text, margin, o estado ng custom na component na hindi na-expose sa pamamagitan ng standard na matchers.

kotlin
// Pagsusuri: TextView ay ipinapakita at naglalaman ng text
onView(withId(R.id.text_welcome))
    .check(matches(isDisplayed()))
    .check(matches(withText("Maligayang pagdating")))

// Pagsusuri: elemento ay HINDI ipinapakita
onView(withId(R.id.progress_bar))
    .check(doesNotExist())

Idling Resources para sa asynchronous operations

Idling Resource ay mekanismo ng Espresso para sa synchronisasyon ng test sa asynchronous operations. Bilang default, naghihintay ang Espresso ng pagkumpleto ng Handler, AsyncTask at coroutines (sa pamamagitan ng coroutinesIdlingResource). Kung ang application ay gumagawa ng background work sa pamamagitan ng sarili nitong threads o Callback services, kailangan mag-register ng custom na Idling Resource.

Halimbawa sa coroutines

Mula sa AndroidX Test 1.4.0, sinusuportahan ng Espresso ang coroutines sa pamamagitan ng CoroutinesIdlingResource. Ang test ay awtomatikong naghihintay ng pagkumpleto ng lahat ng inilunsad na coroutines bago magsagawa ng UI checks. Para sa mas kumplikadong scenarios, ginagamit ang CountingIdlingResource — counter na tumataas sa pagsisimula ng task at bumababa sa pagkumpleto.

kotlin
// Pagrehistro ng IdlingResource para sa OkHttp
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
    }
}

Pag-setup ng Espresso sa Android project

Pagkonekta ng Espresso sa Android project ay ginagawa sa pamamagitan ng pagdadagdag ng dependencies sa build.gradle ng module level. Ang Espresso ay bahagi ng AndroidX Test, kaya sapat na upang tukuyin ang dependencies para sa Espresso core, extensions at JUnit integration. Ang mga test ay inilalagay sa directory na src/androidTest at pinapatakbo sa physical device o emulator sa pamamagitan ng AndroidJUnitRunner.

Gradle Configuration

Ang minimal na set ng dependencies ay kinabibilangan ng espresso-core (core), espresso-contrib (karagdagang matchers para sa RecyclerView, Drawer, Picker) at runner (AndroidX test runner). Lahat ng test ay pinapatakbo sa emulator o physical device sa pamamagitan ng Android Test Orchestrator.

kotlin
// build.gradle.kts (androidTest dependencies)
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")
}

Pagpapatakbo ng tests sa CI

Ang Espresso tests ay maaaring patakbuhin sa pamamagitan ng Google Android Test Orchestrator, na nag-iisolate ng bawat test sa isang hiwalay na process at naglilinis ng estado sa pagitan ng mga pagpapatakbo. Ito ay nag-aalis ng flaky tests na nauugnay sa natitirang data mula sa nakaraang tests at nagpapataas ng stability sa CI servers. Para sa parallel execution, ginagamit ang sharding — pamamahagi ng tests sa pagitan ng maraming emulator.

Mga Madalas Itanong

Ano ang pagkakaiba ng Espresso sa UI Automator?

Espresso ay gumagana sa loob ng process ng application at gumagamit ng awtomatikong synchronisasyon sa UI thread. Ang UI Automator ay gumagana sa system level, maaaring makipag-ugnayan sa ibang applications, ngunit nangangailangan ng manual na pamamahala ng paghihintay.

Bakit tinatawag na “three-legged dog” framework ang Espresso?

Ito ay metapora mula sa Google presentation: ang Espresso test ay nakatayo sa tatlong haligi — ViewMatcher (paghahanap), ViewAction(aksyon) at ViewAssertion(pagsusuri). Kung alisin ang alinman sa kanila, ang test ay nawawalan ng stability, tulad ng isang three-legged dog.

Paano i-test ang RecyclerView gamit ang Espresso?

Para sa RecyclerView, ginagamit ang library na espresso-contrib at methods na onView(withId(R.id.recycler)).perform(actionOnItemAtPosition(0,click())). Alternatibo — onData() para sa AdapterView o custom na ViewAction para sa paghahanap ng elemento ayon sa text sa loob ng RecyclerView. Dagdag pa, maaaring gamitin ang RecyclerViewActions mula sa espresso-contrib para sa pag-scroll sa elemento at mga aksyon dito.

Ano ang flaky test at paano ito nilalabanan ng Espresso?

Flaky test ay test na paminsan-minsan ay nabibigo nang walang pagbabago sa code, dahil sa race condition o asynchronicity. Nilulutas ng Espresso ang problemang ito sa pamamagitan ng Idling Resource — paghihintay ng pagkumpleto ng lahat ng background tasks bago magsagawa ng pagsusuri.

Maaari bang gamitin ang Espresso para sa screenshot testing?

Ang Espresso mismo ay hindi dinisenyo para sa screenshot tests, ngunit maaari itong pagsamahin sa mga library tulad ng Shot o Paparazzi. Inihahanda ng Espresso ang UI sa nais na estado, at ang comparison library ay kumukuha ng screenshot at ikinukumpara ito sa reference. Ang approach na ito ay tinatawag na visual regression testing at tumutulong sa paghahanap ng hindi inaasahang pagbabago sa interface.

Buod

  • Espresso — Android UI testing framework mula sa Google na may awtomatikong synchronisasyon.
  • ViewMatchers — API para sa paghahanap ng elements ayon sa ID, text, hierarchy at combinations.
  • ViewActions — click, typeText, scrollTo, swipe para sa pakikipag-ugnayan sa UI.
  • ViewAssertions — matches, doesNotExist para sa pagsusuri ng estado ng elements.
  • Idling Resource — synchronisasyon ng test sa asynchronous operations at coroutines.
  • Tatlong hakbang — onView().perform().check() = hanapin, gawin, suriin.
  • AndroidX Test — mga library para sa pagpapatakbo ng instrumental tests sa emulator o device.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din