Espresso-Web est un point d'entrée pour travailler avec les composants d'interface utilisateur Android WebView. Espresso-Web réutilise les Atoms de la célèbre API WebDriver pour examiner et contrôler le comportement d'une WebView.
Quand utiliser Espresso-Web ?
Utilisez Espresso-Web pour tester vos applications hybrides, en particulier l'intégration des composants d'UI natifs de votre application avec ses composants d'UI WebView
. Vous pouvez utiliser l'API Espresso-Web en association avec d'autres API Espresso pour interagir pleinement avec les éléments Web à l'intérieur des objets WebView
.
Si vous n'avez besoin de tester que le WebView
lui-même, et non les interactions entre le WebView
et les composants natifs de votre application, envisagez d'écrire un test Web général à l'aide d'un framework tel que WebDriver.WebView
Si vous utilisez un framework de test Web, vous n'avez pas besoin d'utiliser un appareil Android ni une machine virtuelle Java, ce qui permet à vos tests de s'exécuter plus rapidement et de manière plus fiable. Cela dit, Espresso-Web vous permet de réutiliser vos atomes WebDriver personnalisés, ce qui vous offre une grande flexibilité, en particulier lorsque vous écrivez des tests que vous prévoyez d'exécuter sur des applications Web autonomes et sur des applications qui incluent une interface utilisateur Android.
Fonctionnement
Comme la méthode onData()
d'Espresso, une interaction WebView
comprend plusieurs Atoms.
Les interactions WebView
utilisent une combinaison du langage de programmation Java et d'un pont JavaScript pour fonctionner. Comme il n'y a aucun risque d'introduire des conditions de course en exposant des données de l'environnement JavaScript (tout ce qu'Espresso voit du côté Java est une copie isolée), le renvoi de données à partir d'objets Web.WebInteraction
est entièrement pris en charge, ce qui vous permet de vérifier toutes les données renvoyées par une requête.
Qu'est-ce qu'un atome WebDriver ?
Le framework WebDriver utilise des Atoms pour trouver et manipuler des éléments Web de manière programmatique. WebDriver utilise des atomes pour permettre la manipulation du navigateur. Un atome est conceptuellement semblable à un ViewAction
, une unité autonome qui effectue une action dans votre UI. Vous exposez les Atoms à l'aide d'une liste de méthodes définies, telles que findElement()
et getElement()
, pour piloter le navigateur du point de vue de l'utilisateur. Toutefois, si vous utilisez directement le framework WebDriver, les Atoms doivent être correctement orchestrés, ce qui nécessite une logique assez verbeuse.
Dans Espresso, les classes Web
et Web.WebInteraction
encapsulent ce code standard et donnent l'impression d'interagir avec des objets WebView comme avec Espresso. Dans le contexte d'un WebView
, les Atoms sont utilisés en remplacement des ViewMatchers
et ViewActions
Espresso traditionnels.
L'API semble alors assez simple :
Kotlin
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion)
Java
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion);
Pour en savoir plus, consultez la documentation de Selenium sur les Atoms.
Implémenter WebView
Suivez les conseils des sections suivantes pour utiliser WebView
dans les tests de votre application.
Packages
Pour inclure Espresso-Web dans votre projet, procédez comme suit :
- Ouvrez le fichier
build.gradle
de votre application. Il ne s'agit généralement pas du fichierbuild.gradle
de premier niveau, mais deapp/build.gradle
. Ajoutez la ligne suivante dans les dépendances :
Groovy
androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
Espresso-Web n'est compatible qu'avec Espresso 2.2 ou version ultérieure et la version 0.3 ou ultérieure de la bibliothèque de test. Assurez-vous donc de mettre à jour ces lignes également :
Groovy
androidTestImplementation 'androidx.test:runner:1.6.1' androidTestImplementation 'androidx.test:rules:1.6.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
Kotlin
androidTestImplementation('androidx.test:runner:1.6.1') androidTestImplementation('androidx.test:rules:1.6.1') androidTestImplementation('androidx.test.espresso:espresso-core:3.6.1')
Utilisation courante de l'API
La méthode onWebView()
est le principal point d'entrée lorsque vous travaillez avec WebView sur Android à l'aide d'Espresso. Vous utilisez cette méthode pour effectuer des tests Espresso-Web, tels que les suivants :
Kotlin
onWebView() .withElement(findElement(Locator.ID, "link_2")) // similar to onView(withId(...)) .perform(webClick()) // Similar to perform(click()) // Similar to check(matches(...)) .check(webMatches(getCurrentUrl(), containsString("navigation_2.html")))
Java
onWebView() .withElement(findElement(Locator.ID, "link_2")) // similar to onView(withId(...)) .perform(webClick()) // Similar to perform(click()) // Similar to check(matches(...)) .check(webMatches(getCurrentUrl(), containsString("navigation_2.html")));
Dans cet exemple, Espresso-Web localise un élément DOM dont l'ID est "link_2"
et clique dessus. L'outil vérifie ensuite que la WebView envoie une requête GET contenant la chaîne "navigation_2.html"
.
Compatibilité avec JavaScript
Lors de l'exécution de vos tests, le système effectue toutes les interactions WebView à l'aide de JavaScript. Par conséquent, pour prendre en charge l'évaluation JavaScript, JavaScript doit être activé dans la WebView testée.
Vous pouvez forcer l'activation de JavaScript en appelant forceJavascriptEnabled()
en tant qu'action dans votre activité en cours de test, comme indiqué dans l'extrait de code suivant.
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule val activityScenarioRule = activityScenarioRule<MyWebViewActivity>() @Test fun testWebViewInteraction() { onWebView().forceJavascriptEnabled() } }
Interactions Web courantes
Voici quelques exemples d'interactions courantes avec les objets Web.WebInteraction
:
-
withElement()
fait référence à un élément DOM dans le WebView.Exemple :
Kotlin
onWebView().withElement(findElement(Locator.ID, "teacher"))
Java
onWebView().withElement(findElement(Locator.ID, "teacher"));
-
withContextualElement()
fait référence à un élément DOM à portée limitée dans la WebView, par rapport à un autre élément DOM. Vous devez d'abord appelerwithElement()
pour établir l'objetWeb.WebInteraction
de référence (élément DOM).Exemple :
Kotlin
.withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name"))
Java
.withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name"));
-
check()
évalue une condition et s'assure qu'elle est résolue entrue
.Exemple :
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name")) .check(webMatches(getText(), containsString("Socrates")))
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name")) .check(webMatches(getText(), containsString("Socrates")));
-
perform()
exécute une action dans une WebView, comme cliquer sur un élément.Exemple :
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick())
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick());
-
reset()
rétablit l'état initial de WebView. Cela est nécessaire lorsqu'une action précédente, telle qu'un clic, introduit un changement de navigation qui rend les objets ElementReference et WindowReference inaccessibles.Remarque : Bien que l'utilisation de
reset()
soit utile pour effectuer des assertions sur des workflows multipages, tels que les envois de formulaires, vos tests doivent généralement être de portée limitée et se concentrer sur une seule page.Exemple :
Kotlin
onWebView() .withElement(...) .perform(...) .reset()
Java
onWebView() .withElement(...) .perform(...) .reset();
Exemple
L'exemple suivant teste si, après avoir saisi du texte dans une WebView et sélectionné un bouton Envoyer, le même texte apparaît dans un autre élément de la même WebView :
Kotlin
const val MACCHIATO = "Macchiato" @RunWith(AndroidJUnit4::class) class MyEspressoWebTestSuite { @Test fun typeTextInInput_clickButton_SubmitsForm() { // Create an intent that displays a web form. val webFormIntent = Intent() // ... // Lazily launch the Activity with a custom start Intent per test. ActivityScenario.launchActivity(webFormIntent) // Selects the WebView in your layout. If you have multiple WebView // objects, you can also use a matcher to select a given WebView, // onWebView(withId(R.id.web_view)). onWebView() // Find the input element by ID. .withElement(findElement(Locator.ID, "text_input")) // Clear previous input and enter new text into the input element. .perform(clearElement()) .perform(DriverAtoms.webKeys(MACCHIATO)) // Find the "Submit" button and simulate a click using JavaScript. .withElement(findElement(Locator.ID, "submitBtn")) .perform(webClick()) // Find the response element by ID, and verify that it contains the // entered text. .withElement(findElement(Locator.ID, "response")) .check(webMatches(getText(), containsString(MACCHIATO))) } }
Java
public static final String MACCHIATO = "Macchiato"; @Test public void typeTextInInput_clickButton_SubmitsForm() { // Create an intent that displays a web form. Intent webFormIntent = new Intent(); // ... // Lazily launch the Activity with a custom start Intent per test. ActivityScenario.launchActivity(webFormIntent); // Selects the WebView in your layout. If you have multiple WebView objects, // you can also use a matcher to select a given WebView, // onWebView(withId(R.id.web_view)). onWebView() // Find the input element by ID. .withElement(findElement(Locator.ID, "text_input")) // Clear previous input and enter new text into the input element. .perform(clearElement()) .perform(DriverAtoms.webKeys(MACCHIATO)) // Find the "Submit" button and simulate a click using JavaScript. .withElement(findElement(Locator.ID, "submitBtn")) .perform(webClick()) // Find the response element by ID, and verify that it contains the // entered text. .withElement(findElement(Locator.ID, "response")) .check(webMatches(getText(), containsString(MACCHIATO))); }
Ressources supplémentaires
Pour en savoir plus sur l'utilisation d'Espresso-Web dans les tests Android, consultez les ressources suivantes.
Exemples
- WebBasicSample :
Utilisez Espresso-Web pour interagir avec les objets
WebView
.