Espresso — ce que c'est, principes de fonctionnement et comment l'utiliser

Auteur : IT Sectr Publié le : 2026-04-08 Temps de lecture : 8 min

Espresso est un framework de tests d'interface utilisateur automatisés pour applications Android, développé par l'équipe Google et faisant partie d'AndroidX Test. Contrairement aux tests instrumentés qui vérifient des composants isolés, Espresso interagit avec l'interface réelle : il clique sur les boutons, saisit du texte et vérifie l'affichage des éléments. Selon Google Android Developers, Espresso offre une synchronisation automatique avec le thread d'interface utilisateur, éliminant le besoin de Thread.sleep() manuel.

Points essentiels

  • Espresso — framework de tests d'interface Android avec synchronisation automatique des threads.
  • ViewMatcher — localise les éléments View à l'écran par ID, texte ou hiérarchie parente.
  • ViewAction — effectue des actions sur l'élément : clic, saisie de texte, balayage.
  • ViewAssertion — vérifie l'état de l'élément : affiché, contient du texte, actif.
  • Idling Resource — mécanisme d'attente de fin des opérations asynchrones avant de vérifier l'interface.

Qu'est-ce qu'Espresso ?

Espresso est une bibliothèque pour écrire des tests d'interface utilisateur automatisés pour Android, faisant partie de Google AndroidX Test. Elle fournit une API pour trouver des éléments View à l'écran, effectuer des actions sur eux (clic, saisie, balayage) et vérifier leur état (affiché, contient du texte, activé).

La caractéristique clé d'Espresso est la synchronisation automatique avec le thread principal de l'application. Le framework attend la fin de toutes les tâches asynchrones (coroutines, AsyncTask, Handler) avant d'exécuter la vérification suivante. Cela élimine les tests instables causés par les conditions de concurrence et rend les tests d'interface stables et fiables — aucun test ne contient de Thread.sleep() ou de boucles d'attente.

Espresso suit le principe du Chien à Trois Pattes — un test comprend trois étapes : trouver un élément (ViewMatcher), effectuer une action (ViewAction), vérifier le résultat (ViewAssertion). Les trois étapes s'écrivent dans une chaîne d'appels : onView().perform().check(). Ce concept rend les tests prévisibles et faciles à lire — chaque test décrit explicitement ce qu'il cherche, ce qu'il fait et ce qu'il vérifie.

Comment fonctionne Espresso

Architecture d'Espresso repose sur trois composants : Espresso (point d'entrée — méthodes statiques onView et onData), ViewMatchers (recherche d'éléments), ViewActions (actions) et ViewAssertions (vérifications). En interne, le framework utilise Idling Resource pour la synchronisation avec le thread d'interface.

Test Espresso de base

Le test le plus simple trouve un bouton par son ID, effectue un clic et vérifie que le texte « Terminé » apparaît. Toutes les opérations sont synchrones du point de vue du test — Espresso garantit que le thread d'interface a terminé le traitement de l'événement avant que le test ne continue. Ceci est réalisé grâce à un mécanisme d'attente intégré : onView bloque l'exécution du test jusqu'à ce que l'interface soit inactive.

kotlin
@Test
fun buttonClick_showsSuccessText() {
    // Trouver le bouton par ID et cliquer
    onView(withId(R.id.button_submit))
        .perform(click())

    // Vérifier que le texte « Terminé » est affiché
    onView(withText("Terminé"))
        .check(matches(isDisplayed()))
}

Règle ActivityScenario

Pour lancer un test Espresso, on utilise ActivityScenario (AndroidX Test), qui crée une Activity dans un état spécifique — en cours d'exécution, en pause ou détruite. ActivityScenario permet de tester le cycle de vie de l'Activity en plus des tests d'interface purs. Par exemple, on peut vérifier que les données sont conservées lors de la rotation de l'écran (recréation de l'Activity) et restaurées après destruction.

ViewMatchers est un ensemble de méthodes de la classe Espresso.onView qui permettent de trouver des Views à l'écran selon différents critères : ID de ressource (R.id), texte, indice, élément parent et hiérarchie. Si un matcher ne donne pas de résultat unique, les matchers peuvent être combinés avec allOf().

MatcherFonction
withId(R.id.name)Recherche par ID de ressource
withText(« texte »)Recherche par texte affiché
withHint(« indice »)Recherche par attribut hint d'EditText
isDisplayed()Vérifie que l'élément est visible à l'écran
hasSibling(matcher)Recherche par élément frère
allOf(m1, m2)Combinaison de plusieurs matchers

Combinaison de matchers

Si plusieurs éléments identiques sont présents à l'écran (par exemple, deux TextView avec du texte différent), il est pratique de combiner les matchers avec allOf : onView(allOf(withId(R.id.title), withText(« Bonjour »))). Cela garantit la sélection d'un élément unique. L'opérateur inverse — not() — exclut des éléments de la recherche, et hasSibling() trouve un élément à côté d'un élément connu.

ViewActions : interaction avec l'interface

ViewActions sont des actions qu'Espresso effectue sur la View trouvée : click(), typeText(), clearText(), scrollTo(), swipeLeft() et autres. Les actions sont passées à la méthode perform(), qui peut accepter plusieurs actions à la suite.

Chaînage d'actions

La méthode perform() accepte vararg ViewAction, permettant d'exécuter une séquence d'actions sur un élément : effacer le champ, saisir un nouveau texte, fermer le clavier et cliquer sur un bouton. Toutes les actions s'exécutent dans l'ordre où elles sont listées, et Espresso garantit que l'action précédente est terminée avant que la suivante ne commence.

kotlin
// Saisir du texte dans EditText et cliquer sur le bouton
onView(withId(R.id.edit_email))
    .perform(
        clearText(),
        typeText("user@example.com"),
        closeSoftKeyboard()
    )

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

Vérification via onData

Pour les éléments dans AdapterView (ListView, RecyclerView), on utilise la méthode onData() au lieu de onView. Elle travaille avec les données de l'adaptateur plutôt qu'avec les Views — elle trouve un élément par le contenu du modèle et retourne la View correspondante pour les actions suivantes. onData utilise des matchers hamcrest pour localiser un élément par les champs de données du modèle.

ViewAssertions : vérification d'état

ViewAssertions vérifient qu'une View est dans un état spécifique. La méthode de base — matches(matcher) — vérifie que l'élément correspond au matcher donné. De plus, Espresso propose doesNotExist() (élément absent) et selectedDescendantsMatch() (vérification des éléments imbriqués).

Vérifications typiques

Les vérifications les plus fréquentes dans les tests d'interface : l'élément est affiché (isDisplayed), l'élément contient un texte spécifique (withText), l'élément est activé (isEnabled), l'élément n'est pas coché (isNotChecked). Chaque vérification lève une exception détaillée en cas d'échec — incluant la hiérarchie des Views à l'écran. Cela simplifie le débogage : le message d'erreur montre quels éléments étaient réellement à l'écran au moment de la vérification.

ViewAssertions personnalisées

Si les vérifications standard sont insuffisantes, on peut en créer une personnalisée via l'interface ViewAssertion. Une assertion personnalisée reçoit une View et peut vérifier son état par programmation — par exemple, la couleur du texte, les marges intérieures ou l'état d'un composant personnalisé non exposé via les matchers standard.

kotlin
// Vérification : TextView est affiché et contient du texte
onView(withId(R.id.text_welcome))
    .check(matches(isDisplayed()))
    .check(matches(withText("Bienvenue")))

// Vérification : l'élément N'est PAS affiché
onView(withId(R.id.progress_bar))
    .check(doesNotExist())

Idling Resources pour opérations asynchrones

Idling Resource est le mécanisme d'Espresso pour synchroniser le test avec les opérations asynchrones. Par défaut, Espresso attend Handler, AsyncTask et les coroutines (via coroutinesIdlingResource). Si l'application effectue un travail en arrière-plan via des threads personnalisés ou des services de rappel, il faut enregistrer une Idling Resource personnalisée.

Exemple avec coroutines

À partir d'AndroidX Test 1.4.0, Espresso prend en charge les coroutines via CoroutinesIdlingResource. Le test attend automatiquement la fin de toutes les coroutines lancées avant d'effectuer des vérifications d'interface. Pour les scénarios plus complexes, on utilise CountingIdlingResource — un compteur qui s'incrémente au début d'une tâche et se décrémente à la fin.

kotlin
// Enregistrer IdlingResource pour 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
    }
}

Configuration d'Espresso dans un projet Android

Intégration d'Espresso dans un projet Android se fait en ajoutant des dépendances dans le build.gradle au niveau du module. Espresso fait partie d'AndroidX Test, il suffit donc de spécifier les dépendances pour le noyau Espresso, les extensions et l'intégration JUnit. Les tests sont placés dans le répertoire src/androidTest et exécutés sur un appareil physique ou un émulateur via AndroidJUnitRunner.

Configuration Gradle

L'ensemble minimal de dépendances inclut espresso-core (noyau), espresso-contrib (matchers supplémentaires pour RecyclerView, Drawer, Picker) et runner (exécuteur de tests AndroidX). Tous les tests sont exécutés sur un émulateur ou un appareil physique via Android Test Orchestrator.

kotlin
// build.gradle.kts (dépendances 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")
}

Exécution des tests sur CI

Les tests Espresso peuvent être exécutés via Google Android Test Orchestrator, qui isole chaque test dans un processus séparé et nettoie l'état entre les exécutions. Cela élimine les tests instables causés par les données résiduelles des tests précédents et améliore la stabilité sur les serveurs CI. Pour l'exécution parallèle, on utilise le sharding — répartition des tests entre plusieurs émulateurs.

Questions fréquentes

Quelle est la différence entre Espresso et UI Automator ?

Espresso fonctionne à l'intérieur du processus de l'application et utilise la synchronisation automatique avec le thread d'interface. UI Automator fonctionne au niveau système, peut interagir avec d'autres applications, mais nécessite une gestion manuelle de l'attente.

Pourquoi Espresso est-il appelé le framework au « chien à trois pattes » ?

C'est une métaphore d'une présentation Google : un test Espresso repose sur trois piliers — ViewMatcher (trouver), ViewAction(agir) et ViewAssertion(vérifier). En retirer un rend le test instable, comme un chien à trois pattes.

Comment tester RecyclerView avec Espresso ?

Pour RecyclerView, on utilise la bibliothèque espresso-contrib et des méthodes comme onView(withId(R.id.recycler)).perform(actionOnItemAtPosition(0, click())). Une alternative est onData() pour AdapterView ou un ViewAction personnalisé pour trouver un élément par texte dans RecyclerView. De plus, RecyclerViewActions d'espresso-contrib peut être utilisé pour faire défiler jusqu'à un élément et effectuer des actions dessus.

Qu'est-ce qu'un test instable (flaky) et comment Espresso le gère-t-il ?

Un test instable est un test qui échoue parfois sans modification du code, à cause de conditions de concurrence ou d'asynchronisme. Espresso résout ce problème avec Idling Resource — attendre la fin de toutes les tâches en arrière-plan avant d'effectuer les vérifications.

Peut-on utiliser Espresso pour les tests de capture d'écran ?

Espresso lui-même n'est pas conçu pour les tests de capture d'écran, mais il peut être combiné avec des bibliothèques comme Shot ou Paparazzi. Espresso prépare l'interface dans l'état souhaité, et la bibliothèque de comparaison prend une capture d'écran et la compare à une référence. Cette approche s'appelle le test de régression visuelle et aide à trouver des changements inattendus dans l'interface.

Résumé

  • Espresso — framework de tests d'interface Android de Google avec synchronisation automatique.
  • ViewMatchers — API pour trouver des éléments par ID, texte, hiérarchie et combinaisons.
  • ViewActions — click, typeText, scrollTo, swipe pour l'interaction avec l'interface.
  • ViewAssertions — matches, doesNotExist pour vérifier l'état des éléments.
  • Idling Resource — synchronisation des tests avec opérations asynchrones et coroutines.
  • Trois étapes — onView().perform().check() = trouver, exécuter, vérifier.
  • AndroidX Test — bibliothèques pour exécuter des tests instrumentés sur émulateur ou appareil.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi