Espresso — τι είναι, αρχές λειτουργίας και πως να χρησιμοποιείται

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-04-08 Χρόνος ανάγνωσης: 8 λεπ

Το Espresso είναι ένα framework για αυτοματοποιημένο UI testing εφαρμογών Android, που αναπτύχθηκε από την ομάδα Google και αποτελεί μέρος του AndroidX Test. Σε αντίθεση με τα οργανικά τεστ που ελέγχουν απομονωμένα στοιχεία, το Espresso αλληλεπιδρά με το πραγματικό UI: πατάει κουμπιά, εισάγει κείμενο, ελέγχει την εμφάνιση στοιχείων. Σύμφωνα με το Google Android Developers, το Espresso παρέχει αυτόματο συγχρονισμό με το UI thread, εξαλείφοντας την ανάγκη για χειροκίνητο Thread.sleep().

Βασικά Σημεία

  • Espresso — framework για UI testing στο Android με αυτόματο συγχρονισμό threads.
  • ViewMatcher — αναζήτηση στοιχείου View στην οθόνη με βάση ID, κείμενο, ιεραρχία γονέα.
  • ViewAction — ενέργεια στο στοιχείο: κλικ, εισαγωγή κειμένου, σβίπ.
  • ViewAssertion — έλεγχος κατάστασης στοιχείου: εμφανίζεται, περιέχει κείμενο, είναι ενεργό.
  • Idling Resource — μηχανισμός αναμονής ολοκλήρωσης ασύγχρονων λειτουργιών πριν από τον έλεγχο UI.

Τι είναι το Espresso;

Το Espresso είναι μια βιβλιοθήκη για τη σύνταξη αυτοματοποιημένων UI tests για Android, η οποία αποτελεί μέρος του Google AndroidX Test. Παρέχει API για την εύρεση στοιχείων View στην οθόνη, την εκτέλεση ενεργειών πάνω τους (κλικ, εισαγωγή, σβίπ) και τον έλεγχο της κατάστασής τους (εμφανίζεται, περιέχει κείμενο, είναι ενεργό).

Το βασικό χαρακτηριστικό του Espresso είναι ο αυτόματος συγχρονισμός με το κύριο thread της εφαρμογής. Το framework περιμένει την ολοκλήρωση όλων των ασύγχρονων εργασιών (coroutines, AsyncTask, Handler) πριν εκτελέσει τον επόμενο έλεγχο. Αυτό εξαλείφει τα flaky tests που σχετίζονται με race conditions και κάνει τα UI tests σταθερά και αξιόπιστα — κανένα test δεν περιέχει Thread.sleep() ή βρόχους αναμονής.

Το Espresso ακολουθεί την αρχή του Three-Legged Dog — ένα test αποτελείται από τρία βήματα: βρείτε το στοιχείο (ViewMatcher), εκτελέστε την ενέργεια (ViewAction), ελέγξτε το αποτέλεσμα (ViewAssertion). Και τα τρία βήματα γράφονται σε μια αλυσίδα κλήσεων onView().perform().check(). Αυτή η αντίληψη κάνει τα tests πρεβλέψιμα και εύκολα αναγνώσιμα — κάθε test περιγράφει ρητά τι ψάχνει, τι κάνει και τι ελέγχει.

Πως λειτουργεί το Espresso

Η αρχιτεκτονική του Espresso βασίζεται σε τρία συστατικά: Espresso (σημείο εισόδου — στατικές μεθοδοι onView και onData), ViewMatchers (αναζήτηση στοιχείων), ViewActions (ενέργειες) και ViewAssertions (έλεγχοι). Εσωτερικά, το framework χρησιμοποιεί Idling Resource για συγχρονισμό με το UI thread.

Βασικό Test Espresso

Ένα απλό test βρίσκει ένα κουμπί από ID, εκτελεί ένα κλικ και ελέγχει αν εμφανίστηκε το κείμενο “Έτοιμο”. Όλες οι λειτουργίες εκτελούνται σύγχρονα από τη σκοπιά του test — το Espresso εγγυάται ότι το UI thread ολοκλήρωσε την επεξεργασία του συμβάντος πριν συνεχιστεί το test. Αυτό επιτυγχάνεται με έναν ενσωματωμένο μηχανισμό αναμονής: το onView μπλοκάρει την εκτέλεση του test μέχρι το UI να γίνει σταθερό.

kotlin
@Test
fun buttonClick_showsSuccessText() {
    // 91bdb1b6aec4b7c3b7 babfc5bcc0b9bfcd bcb5 ID bab1b9 babbb9ba
    onView(withId(R.id.button_submit))
        .perform(click())

    // 88bbb5b3c7bfc2 ccc4b9 c4bf bab5afbcb5bdbf c88c4bfb9bcbfd b5bcc6b1bdafb6b5c4b1b9
    onView(withText("88c4bfb9bcbf"))
        .check(matches(isDisplayed()))
}

Κανόνας ActivityScenario

Για την εκκίνηση ενός test Espresso χρησιμοποιείται το ActivityScenario (AndroidX Test) που δημιουργεί το Activity σε επιθυμητή κατάσταση — σε λειτουργία, σε παύση, κατεστραμμένο. Το ActivityScenario επιτρέπει τη δοκιμή του κύκλου ζωής του Activity παράλληλα με το καθαρό UI. Για παράδειγμα, μπορείτε να ελέγξετε ότι τα δεδομένα αποθηκεύονται κατά την περιστροφή της οθόνης (αναδημιουργία Activity) και αποκαθίστανται μετά από καταστροφή.

Οι ViewMatchers είναι ένα σύνολο μεθόδων από την κλάση Espresso.onView που επιτρέπουν την εύρεση View στην οθόνη με βάση διάφορα κριτήρια: αναγνωριστικό πόρου (R.id), κείμενο, hint, γονικό στοιχείο και ιεραρχία. Αν ένας matcher δεν δίνει μοναδικό αποτέλεσμα, οι matchers συνδυάζονται μέσω allOf().

MatcherΣκοπός
withId(R.id.name)Αναζήτηση βάσει ID πόρου
withText(“κείμενο”)Αναζήτηση βάσει εμφανιζόμενου κειμένου
withHint(“hint”)Αναζήτηση βάσει του hint χαρακτηριστικού EditText
isDisplayed()Έλεγχος ότι το στοιχείο είναι ορατό στην οθόνη
hasSibling(matcher)Αναζήτηση βάσει γειτονικού στοιχείου
allOf(m1, m2)Συνδυασμός πολλών matchers

Συνδυασμός matchers

Αν υπάρχουν πολλά ίδια στοιχεία στην οθόνη (για παράδειγμα, δύο TextView με διαφορετικό κείμενο), είναι βολικό να συνδυάζετε τους matchers μέσω allOf: onView(allOf(withId(R.id.title), withText(“Γειά”))). Αυτό εγγυάται την επιλογή ενός μοναδικού στοιχείου. Ο αντίστροφος τελεστής — not() — αποκλείει στοιχεία από την αναζήτηση, και το hasSibling() βρίσκει ένα στοιχείο δίπλα σε ένα γνωστό.

ViewActions: αλληλεπίδραση με το UI

Οι ViewActions είναι ενέργειες που εκτελεί το Espresso πάνω στο στοιχείο View: click(), typeText(), clearText(), scrollTo(), swipeLeft() και άλλες. Οι ενέργειες μεταβιβάζονται στη μέθοδο perform() η οποία μπορεί να δεχτεί πολλές ενέργειες σειρά.

Αλυσίδα ενεργειών

Η μέθοδος perform() δεχεται vararg ViewAction, που επιτρέπει την εκτέλεση μιας σειράς ενεργειών σέ ένα στοιχείο: καθαρισμός πεδίου, εισαγωγή νέου κειμένου, κλείσιμο πληκτρολογίου και πάτημα κουμπιού. Όλες οι ενέργειες εκτελούνται με τη σειρά που αναφέρονται, και το Espresso εγγυάται ότι η προηγούμενη ενέργεια ολοκληρώθηκε πριν από την έναρξη της επόμενης.

kotlin
// 95b9c3b1b3c9b3ae bab5b9bcadbdbfc5 c3b5 EditText bab1b9 babbb9ba babfc5bcc0b9bfcd
onView(withId(R.id.edit_email))
    .perform(
        clearText(),
        typeText("user@example.com"),
        closeSoftKeyboard()
    )

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

Έλεγχος μέσω onData

Για στοιχεία μέσα σε AdapterView (ListView, RecyclerView) χρησιμοποιείται η μέθοδος onData() αντί για onView. Αυτή εργάζεται με τα δεδομένα του προσαρμοστή, όχι με το View — βρίσκει το στοιχείο βάσει του περιεχομένου του μοντέλου και επιστρέφει το αντίστοιχο View για περαιτέρω ενέργειες. Το onData χρησιμοποιεί hamcrest matchers για την εύρεση του στοιχείου βάσει των πεδίων του μοντέλου δεδομένων.

ViewAssertions: έλεγχος κατάστασης

Οι ViewAssertions ελέγχουν αν το View βρίσκεται σε συγκεκριμένη κατάσταση. Η βασική μέθοδος — matches(matcher) — ελέγχει αν το στοιχείο ταιριάζει με τον δοθέντα matcher. Επιπλέον, το Espresso προσφέρει doesNotExist() (το στοιχείο δεν υπάρχει) και selectedDescendantsMatch() (έλεγχος εμφωλευμένων στοιχείων).

Τυπικοί έλεγχοι

Οι πιο συνηθισμένοι έλεγχοι σε UI tests: το στοιχείο εμφανίζεται (isDisplayed), το στοιχείο περιέχει συγκεκριμένο κείμενο (withText), το στοιχείο είναι ενεργό (isEnabled), το στοιχείο δεν είναι επιλεγμένο (isNotChecked). Κάθε έλεγχος ρίχνει μια λεπτομερή εξαίρεση σε περίπτωση αποτυχίας — με υπόδειξη της View ιεραρχίας στην οθόνη. Αυτό απλοποιεί το debugging: στο μήνυμα σφάλματος φαίνεται ποια στοιχεία ήταν πραγματικά στην οθόνη τη στιγμή του ελέγχου.

Προσαρμοσμένοι ViewAssertions

Αν οι τυπικοί έλεγχοι δεν είναι αρκετοί, μπορείτε να δημιουργήσετε εναν δικό σας μέσω της διεπαφής ViewAssertion. Ένας προσαρμοσμένος assertion λαμβάνει το View και μπορεί να ελέγξει την κατάστασή του προγραμματιστικά — για παράδειγμα, χρώμα κειμένου, περιθώρια ή κατάσταση ενός προσαρμοσμένου στοιχείου που δεν είναι εκτεθειμένο μέσω τυπικών matchers.

kotlin
// 88bbb5b3c7bfc2: TextView b5bcc6b1bdafb6b5c4b1b9 bab1b9 c0b5c1b9adc7b5b9 bab5afbcb5bdbf
onView(withId(R.id.text_welcome))
    .check(matches(isDisplayed()))
    .check(matches(withText("9ab1bbcec2 bfc1afc3b1c4b5")))

// 88bbb5b3c7bfc2: c3c4bfb9c7b5afbf 94959d b5bcc6b1bdafb6b5c4b1b9
onView(withId(R.id.progress_bar))
    .check(doesNotExist())

Idling Resources για ασύγχρονες λειτουργίες

Το Idling Resource είναι ο μηχανισμός του Espresso για τον συγχρονισμό του test με ασύγχρονες λειτουργίες. Από προεπιλογή, το Espresso περιμένει την ολοκλήρωση του Handler, AsyncTask και coroutines (μέσω coroutinesIdlingResource). Αν η εφαρμογή εκτελεί εργασίες υποβάθρου μέσω ιδίων threads ή υπηρεσιών Callback, πρέπει να καταχωρηθεί ένα προσαρμοσμένο Idling Resource.

Παράδειγμα με coroutines

Από το AndroidX Test 1.4.0, το Espresso υποστηρίζει coroutines μέσω CoroutinesIdlingResource. Το test περιμένει αυτόματα την ολοκλήρωση όλων των εκκινηθέντων coroutines πριν εκτελέσει ελέγχους UI. Για πιο σύνθετα σενάρια, χρησιμοποιείται το CountingIdlingResource — ένας απαριθμητής που αυξάνεται κατά την έναρξη της εργασίας και μειώνεται κατά την ολοκλήρωση.

kotlin
// 9ab1c4b1c7cec1b7c3b7 IdlingResource b3b9b1 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
    }
}

Ρύθμιση Espresso σε έργο Android

Σύνδεση Το Espresso συνδέεται σε ένα έργο Android με προσθήκη εξαρτήσεων στο build.gradle επιπέδου module. Το Espresso είναι μέρος του AndroidX Test, οπότε αρκεί να καθορίσετε εξαρτήσεις για τον πυρήνα Espresso, τις επεκτάσεις και την ενσωμάτωση JUnit. Τα tests τοποθετούνται στον κατάλογο src/androidTest και εκτελούνται σε φυσική συσκευή ή εμπλαείωτη μέσω AndroidJUnitRunner.

Ρύθμιση Gradle

Το ελάχιστο σύνολο εξαρτήσεων περιλαμβάνει espresso-core (πυρήνας), espresso-contrib (επιπλέον matchers για RecyclerView, Drawer, Picker) και runner (test runner AndroidX). Όλα τα tests εκτελούνται σε εμπλαείωτη ή φυσική συσκευή μέσω 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")
}

Εκτέλεση tests σε CI

Τα tests Espresso μπορούν να εκτελεστούν μέσω Google Android Test Orchestrator, ο οποίος απομονώνει κάθε test σε ξεχωριστή διεργασία και καθαρίζει την κατάσταση μεταξύ εκτελέσεων. Αυτό εξαλείφει τα flaky tests που σχετίζονται με υπολειπόμενα δεδομένα από προηγούμενα tests και αυξάνει την σταθερότητα σε CI servers. Για παράλληλη εκτέλεση χρησιμοποιείται sharding — κατανομή των tests σε πολλούς εμπλαείωτες.

Συχνές Ερωτήσεις

Σε τι διαφέρει το Espresso από το UI Automator;

Το Espresso λειτουργεί μέσα στη διεργασία της εφαρμογής και χρησιμοποιεί αυτόματο συγχρονισμό με το UI thread. Το UI Automator λειτουργεί σε επίπεδο συστήματος, μπορεί να αλληλεπιδρά με άλλες εφαρμογές, αλλά απαιτεί χειροκίνητη διαχείριση αναμονής.

Γιατί το Espresso ονομάζεται framework με “τριποδικό σκυλί”;

Είναι μια μεταφορά από την παρουσίαση του Google: το test Espresso στήριζεται σε τρεις πυλώνες — ViewMatcher (αναζήτηση), ViewAction(ενέργεια) και ViewAssertion(έλεγχος). Αν απομακρυνθεί οποιαδήποτε από αυτές, το test χάνει την ευστάθεια του, σαν ένα τριποδικό σκυλί.

Πως να δοκιμάσουμε το RecyclerView με το Espresso;

Για RecyclerView χρησιμοποιείται η βιβλιοθήκη espresso-contrib και οι μέθοδοι onView(withId(R.id.recycler)).perform(actionOnItemAtPosition(0, click())). Εναλλακτικά — onData() για AdapterView ή προσαρμοσμένο ViewAction για αναζήτηση στοιχείου βάσει κειμένου μέσα σε RecyclerView. Επιπλέον, μπορείτε να χρησιμοποιήσετε RecyclerViewActions από το espresso-contrib για κύλιση στο στοιχείο και ενέργειες πάνω του.

Τι είναι το flaky test και πως το καταπολεμά το Espresso;

Το flaky test είναι ένα test που μερικές φορές αποτυγχάνει χωρίς αλλαγή κώδικα, λόγω race condition ή ασυγχρονισμού. Το Espresso λύνει αυτό το πρόβλημα μέσω Idling Resource — αναμονή για την ολοκλήρωση όλων των εργασιών υποβάθρου πριν την εκτέλεση του ελέγχου.

Μπορούμε να χρησιμοποιήσουμε το Espresso για δοκιμή σκρινσότ;

Το Espresso αυτό καθαυτό δεν έχει σχεδιαστεί για δοκιμές σκρινσότ, αλλά μπορεί να συνδυαστεί με βιβλιοθήκες όπως Shot ή Paparazzi. Το Espresso προετοιμάζει το UI σε επιθυμητή κατάσταση, και η βιβλιοθήκη σύγκρισης πάρνει ένα σκρινσότ και το συγκρίνει με την αναφορά. Αυτή η προσέγγιση ονομάζεται οπτική δοκιμή παλινδρόμησης και βοηθάει στην εύρεση απροσδόκητων αλλαγών στη διεπαφή.

Περίληψη

  • Espresso — framework UI testing για Android από το Google με αυτόματο συγχρονισμό.
  • ViewMatchers — API για αναζήτηση στοιχείων βάσει ID, κειμένου, ιεραρχίας και συνδυασμών.
  • ViewActions — click, typeText, scrollTo, swipe για αλληλεπίδραση με το UI.
  • ViewAssertions — matches, doesNotExist για έλεγχο κατάστασης στοιχείων.
  • Idling Resource — συγχρονισμός test με ασύγχρονες λειτουργίες και coroutines.
  • Τρία βήματα — onView().perform().check() = βρες, κάνε, έλεγξε.
  • AndroidX Test — βιβλιοθήκες για εκτέλεση οργανικών tests σε εμπλαείωτη ή συσκευή.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης