Espresso — vad är det, arbetsprinciper och hur man använder

Författare: IT Sectr Publicerad: 2026-04-08 Lästid: 8 min

Espresso är ett ramverk för automatiserad UI-testning av Android-applikationer, utvecklat av Google-teamet och en del av AndroidX Test. Till skillnad från instrumentella tester som kontrollerar isolerade komponenter, interagerar Espresso med det verkliga UI:t: trycker på knappar, anger text, kontrollerar visning av element. Enligt Google Android Developers tillhandahåller Espresso automatisk synkronisering med UI-tråden, vilket eliminerar behovet av manuell Thread.sleep().

Huvudpunkter

  • Espresso — Android UI-testramverk med automatisk trådsynkronisering.
  • ViewMatcher — sökning efter View-element på skärmen efter ID, text, förälderhierarki.
  • ViewAction — åtgärd på elementet: klick, textinmatning, svep.
  • ViewAssertion — kontroll av elementstatus: visas, innehåller text, är aktiv.
  • Idling Resource — mekanism för att vänta på slutförande av asynkrona operationer innan UI-kontroll.

Vad är Espresso?

Espresso är ett bibliotek för att skriva automatiserade UI-tester för Android, som är en del av Google AndroidX Test. Det tillhandahåller API för att hitta View-element på skärmen, utföra åtgärder på dem (klicka, mata in, svepa) och kontrollera deras status (visas, innehåller text, är aktiv).

Den viktigaste funktionen hos Espresso är automatisk synkronisering med applikationens huvudtråd. Ramverket väntar på slutförande av alla asynkrona uppgifter (coroutines, AsyncTask, Handler) innan det utför nästa kontroll. Detta eliminerar flaky-tester relaterade till race condition och gör UI-tester stabila och pålitliga — inget test innehåller Thread.sleep() eller vänteloopar.

Espresso följer principen Three-Legged Dog — ett test består av tre steg: hitta elementet (ViewMatcher), utföra åtgärden (ViewAction), kontrollera resultatet (ViewAssertion). Alla tre stegen skrivs i en kedja av anrop onView().perform().check(). Detta koncept gör tester förutsägbara och lättlästa — varje test beskriver tydligt vad det söker, vad det gör och vad det kontrollerar.

Hur fungerar Espresso

Arkitektur Espresso är baserad på tre komponenter: Espresso (ingångspunkt — statiska metoder onView och onData), ViewMatchers (sökning av element), ViewActions (åtgärder) och ViewAssertions (kontroller). Internt använder ramverket Idling Resource för synkronisering med UI-tråden.

Grundläggande Espresso-test

Ett enkelt test hittar en knapp efter ID, utför ett klick och kontrollerar att texten “Klart” visas. Alla operationer utförs synkront ur testets perspektiv — Espresso garanterar att UI-tråden har slutfört händelsebearbetningen innan testet fortsätter. Detta uppnås genom en inbyggd väntemekanism: onView blockerar testutförandet tills UI:t blir stabilt.

kotlin
@Test
fun buttonClick_showsSuccessText() {
    // Hitta knappen efter ID och klicka
    onView(withId(R.id.button_submit))
        .perform(click())

    // Kontrollera att texten “Klart” visas
    onView(withText("Klart"))
        .check(matches(isDisplayed()))
}

ActivityScenario-regeln

För att starta ett Espresso-test används ActivityScenario (AndroidX Test) som skapar Activity i önskat tillstånd — kör, pausad, förstörd. ActivityScenario möjliggör testning av Activitys livscykel vid sidan av rent UI. Till exempel kan man kontrollera att data sparas vid skärmrotation (rekreation av Activity) och återställs efter förstörelse.

ViewMatchers är en uppsättning metoder från klassen Espresso.onView som gör det möjligt att hitta View på skärmen enligt olika kriterier: resursidentifierare (R.id), text, hint-ledtråd, förälderelement och hierarki. Om en matcher inte ger ett unikt resultat kombineras matcher via allOf().

MatcherSyfte
withId(R.id.name)Sökning efter resurs-ID
withText(“text”)Sökning efter visad text
withHint(“ledtråd”)Sökning efter hint-attribut i EditText
isDisplayed()Kontroll av att elementet är synligt på skärmen
hasSibling(matcher)Sökning efter grannelement
allOf(m1, m2)Kombination av flera matchers

Kombination av matchers

Om det finns flera identiska element på skärmen (till exempel två TextView med olika text), är det praktiskt att kombinera matchers via allOf: onView(allOf(withId(R.id.title), withText(“Hej”))). Detta garanterar val av ett unikt element. Den omvända operatorn — not() — utesluter element från sökningen, och hasSibling() söker ett element bredvid ett känt element.

ViewActions: interaktion med UI

ViewActions är åtgärder som Espresso utför på det hittade View:t: click(), typeText(), clearText(), scrollTo(), swipeLeft() och andra. Åtgärder skickas till metoden perform() som kan ta emot flera åtgärder i följd.

Kedja av åtgärder

Metoden perform() accepterar vararg ViewAction, vilket gör det möjligt att utföra en sekvens av åtgärder på ett element: rensa fältet, ange ny text, stäng tangentbordet och tryck på knappen. Alla åtgärder utförs i den ordning de anges, och Espresso garanterar att den föregående åtgärden har slutförts innan nästa påbörjas.

kotlin
// Ange text i EditText och tryck på knappen
onView(withId(R.id.edit_email))
    .perform(
        clearText(),
        typeText("user@example.com"),
        closeSoftKeyboard()
    )

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

Kontroll via onData

För element inuti AdapterView (ListView, RecyclerView) används metoden onData() istället för onView. Den arbetar med adapterdata, inte med View — hittar elementet efter modellinnehåll och returnerar motsvarande View för vidare åtgärder. onData använder hamcrest-matchers för att hitta elementet efter data-modellens fält.

ViewAssertions: kontroll av status

ViewAssertions kontrollerar om View befinner sig i ett visst tillstånd. Grundmetoden — matches(matcher) — kontrollerar om elementet matchar den angivna matchern. Dessutom erbjuder Espresso doesNotExist() (elementet finns inte) och selectedDescendantsMatch() (kontroll av nästlade element).

Typiska kontroller

De vanligaste kontrollerna i UI-tester: elementet visas (isDisplayed), elementet innehåller viss text (withText), elementet är aktivt (isEnabled), elementet är inte valt (isNotChecked). Varje kontroll kastar ett detaljerat undantag vid misslyckande — med angivelse av View-hierarkin på skärmen. Detta förenklar felsökning: i felmeddelandet syns vilka element som faktiskt fanns på skärmen vid kontrollögonblicket.

Anpassade ViewAssertions

Om standardkontrollerna inte räcker kan man skapa en egen via gränssnittet ViewAssertion. En anpassad assertion tar emot View och kan kontrollera dess tillstånd programmatiskt — till exempel textfärg, marginaler eller tillståndet för en anpassad komponent som inte exponeras via standardmatchers.

kotlin
// Kontroll: TextView visas och innehåller text
onView(withId(R.id.text_welcome))
    .check(matches(isDisplayed()))
    .check(matches(withText("Välkommen")))

// Kontroll: element visas INTE
onView(withId(R.id.progress_bar))
    .check(doesNotExist())

Idling Resources för asynkrona operationer

Idling Resource är Espressos mekanism för att synkronisera testet med asynkrona operationer. Som standard väntar Espresso på slutförande av Handler, AsyncTask och coroutines (via coroutinesIdlingResource). Om applikationen utför bakgrundsarbete via egna trådar eller Callback-tjänster måste en anpassad Idling Resource registreras.

Exempel med coroutines

Från och med AndroidX Test 1.4.0 stöder Espresso coroutines via CoroutinesIdlingResource. Testet väntar automatiskt på slutförande av alla startade coroutines innan det utför UI-kontroller. För mer komplexa scenarier används CountingIdlingResource — en räknare som ökar vid start av en uppgift och minskar vid slutförande.

kotlin
// Registrera IdlingResource för 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
    }
}

Konfiguration av Espresso i Android-projekt

Anslutning av Espresso i ett Android-projekt görs genom att lägga till beroenden i build.gradle på modulnivå. Espresso är en del av AndroidX Test, så det räcker med att ange beroenden för Espresso-kärnan, tillägg och JUnit-integration. Tester placeras i katalogen src/androidTest och körs på en fysisk enhet eller emulator via AndroidJUnitRunner.

Gradle-konfiguration

Den minimala uppsättningen beroenden inkluderar espresso-core (kärna), espresso-contrib (extra matchers för RecyclerView, Drawer, Picker) och runner (AndroidX testlöpare). Alla tester körs på emulator eller fysisk enhet via 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")
}

Körning av tester på CI

Espresso-tester kan köras via Google Android Test Orchestrator, som isolerar varje test i en separat process och rensar tillstånd mellan körningar. Detta eliminerar flaky-tester relaterade till kvarvarande data från tidigare tester och ökar stabiliteten på CI-servrar. För parallell körning används sharding — distribution av tester mellan flera emulatorer.

Vanliga frågor

Vad är skillnaden mellan Espresso och UI Automator?

Espresso arbetar inom applikationsprocessen och använder automatisk synkronisering med UI-tråden. UI Automator arbetar på systemnivå, kan interagera med andra appar men kräver manuell hantering av väntan.

Varför kallas Espresso för “trebenig hund”-ramverket?

Det är en metafor från Googles presentation: Espresso-testet står på tre pelare — ViewMatcher (sökning), ViewAction(åtgärd) och ViewAssertion(kontroll). Om någon av dem tas bort förlorar testet stabilitet, som en trebenig hund.

Hur testar man RecyclerView med Espresso?

För RecyclerView används biblioteket espresso-contrib och metoderna onView(withId(R.id.recycler)).perform(actionOnItemAtPosition(0, click())). Alternativ — onData() för AdapterView eller en anpassad ViewAction för att söka element efter text i RecyclerView. Dessutom kan RecyclerViewActions från espresso-contrib användas för att scrolla till elementet och utföra åtgärder på det.

Vad är ett flaky-test och hur bekämpar Espresso det?

Flaky-test är ett test som ibland misslyckas utan kodändringar, på grund av race condition eller asynkronitet. Espresso löser detta problem genom Idling Resource — väntan på slutförande av alla bakgrundsuppgifter innan kontrollen utförs.

Kan Espresso användas för skärmbildstestning?

Espresso i sig är inte avsett för skärmbildstester, men kan kombineras med bibliotek som Shot eller Paparazzi. Espresso förbereder UI:t i önskat tillstånd, och jämförelsebiblioteket tar en skärmbild och jämför med en referens. Detta tillvägagångssätt kallas visuell regressionstestning och hjälper till att hitta oväntade förändringar i gränssnittet.

Sammanfattning

  • Espresso — Android UI-testramverk från Google med automatisk synkronisering.
  • ViewMatchers — API för att söka element efter ID, text, hierarki och kombinationer.
  • ViewActions — click, typeText, scrollTo, swipe för interaktion med UI.
  • ViewAssertions — matches, doesNotExist för kontroll av elementstatus.
  • Idling Resource — synkronisering av test med asynkrona operationer och coroutines.
  • Tre steg — onView().perform().check() = hitta, gör, kontrollera.
  • AndroidX Test — bibliotek för att köra instrumentella tester på emulator eller enhet.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också