Espresso-Web es un punto de entrada para trabajar con los componentes de la IU de Android WebView. Espresso-Web reutiliza los Atoms de la popular API WebDriver para examinar y controlar el comportamiento de un WebView.
Cuándo usar Espresso-Web
Usa Espresso-Web para probar tus apps híbridas, en especial, la integración de los componentes nativos de la IU de tu app con los componentes de la IU de WebView
. Puedes usar la API de Espresso-Web junto con otras APIs de Espresso para interactuar completamente con elementos web dentro de objetos WebView
.
Si solo necesitas probar el WebView
en sí y no las interacciones entre WebView
y los componentes nativos de tu app, procura escribir una prueba web general con un framework como WebDriver. Si usas un framework de pruebas web, no necesitas usar un dispositivo Android o una máquina virtual Java, lo que hace que tus pruebas se ejecuten de forma más rápida y confiable. Dicho esto, Espresso-Web te permite reutilizar tus átomos personalizados de WebDriver, lo que te brinda mucha flexibilidad, en especial cuando escribes pruebas que planeas ejecutar en apps web independientes y en apps que incluyen una IU de Android.
Cómo funciona
Al igual que el método onData()
de Espresso, una interacción WebView
incluye varios Atoms.
Las interacciones de WebView
usan una combinación de lenguaje de programación Java y un puente JavaScript para hacer el trabajo. Como no es posible introducir condiciones de carrera mediante la exposición de datos del entorno de JavaScript (todo lo que Espresso ve en el lado basado en Java es una copia aislada), los datos que se muestran de objetos Web.WebInteraction
son totalmente compatibles, lo que te permite verificar todos los datos que se muestran desde una solicitud.
¿Qué es un Atom de WebDriver?
El framework de WebDriver usa Atoms para buscar y manipular elementos web de manera programática. WebDriver los utiliza para permitir la manipulación del navegador. Conceptualmente, un Atom es similar a un ViewAction
, una unidad independiente que realiza una acción en tu IU. Puedes exponer los Atoms con una lista de métodos definidos, como findElement()
y getElement()
, para dirigir el navegador desde el punto de vista del usuario. Sin embargo, si usas el framework de WebDriver directamente, los Atoms deben estar organizados de forma correcta, lo que requiere una lógica bastante detallada.
En Espresso, las clases Web
y Web.WebInteraction
unen este código estándar y dan una apariencia de Espresso a la interacción con objetos WebView. Por lo tanto, en el contexto de un WebView
, los Atoms se usan como una sustitución de ViewMatchers
y ViewActions
tradicionales de Espresso.
La API parece bastante simple:
Kotlin
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion)
Java
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion);
Para obtener más información, consulta la documentación de Selenium sobre Atoms.
Cómo implementar WebView
Sigue las instrucciones que se muestran en las siguientes secciones para trabajar con WebView
en las pruebas de tu app.
Paquetes
Para incluir Espresso-Web en tu proyecto, completa los siguientes pasos:
- Abre el archivo
build.gradle
de tu app. Por lo general, este no es el archivobuild.gradle
de nivel superior, sinoapp/build.gradle
. Agrega la siguiente línea dentro de las dependencias:
Groovy
androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
Espresso-Web solo es compatible con Espresso 2.2 o versiones posteriores y con la versión 0.3 o posterior de la biblioteca de pruebas. Por lo tanto, asegúrate de actualizar también esas líneas:
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')
Usos comunes de API
El método onWebView()
es el punto de entrada principal cuando se trabaja con WebView en Android usando Espresso. Usa este método para realizar pruebas de Espresso-Web, como las siguientes:
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")));
En este ejemplo, Espresso-Web localiza un elemento DOM cuyo ID es "link_2"
y hace clic en él. Luego, la herramienta verifica que WebView envíe una solicitud GET que contenga la cadena "navigation_2.html"
.
Compatibilidad con JavaScript
Cuando se ejecutan las pruebas, el sistema realiza todas las interacciones de WebView con JavaScript. Por lo tanto, para admitir la evaluación de JavaScript, la WebView en modo de prueba debe tener JavaScript habilitado.
Para forzar la habilitación de JavaScript, llama a forceJavascriptEnabled()
como una acción en la actividad que estás probando, como se muestra en el siguiente fragmento de código.
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule val activityScenarioRule = activityScenarioRule<MyWebViewActivity>() @Test fun testWebViewInteraction() { onWebView().forceJavascriptEnabled() } }
Interacciones web comunes
Las interacciones comunes con los objetos Web.WebInteraction
incluyen lo siguiente:
-
withElement()
hace referencia a un elemento DOM dentro de WebView.Ejemplo:
Kotlin
onWebView().withElement(findElement(Locator.ID, "teacher"))
Java
onWebView().withElement(findElement(Locator.ID, "teacher"));
-
withContextualElement()
hace referencia a un elemento DOM dentro del alcance dentro de WebView, en relación con otro elemento DOM. Primero, debes llamar awithElement()
para establecer el objetoWeb.WebInteraction
de referencia (elemento DOM).Ejemplo:
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()
evalúa una condición y se asegura de que se resuelva comotrue
.Ejemplo:
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()
ejecuta una acción dentro de WebView, como hacer clic en un elemento.Ejemplo:
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick())
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick());
-
reset()
revierte WebView a su estado inicial. Esto es necesario cuando una acción previa, como un clic, introduce un cambio de navegación que hace que los objetos ElementReference y WindowReference sean inaccesibles.Nota: Aunque el uso de
reset()
es útil cuando se realizan aserciones en flujos de trabajo de varias páginas, como los envíos de formularios, las pruebas en general deben tener un alcance limitado y enfocarse en una sola página.Ejemplo:
Kotlin
onWebView() .withElement(...) .perform(...) .reset()
Java
onWebView() .withElement(...) .perform(...) .reset();
Ejemplo
En el siguiente ejemplo, se prueba si, después de ingresar texto en una WebView y seleccionar un botón Enviar, aparece el mismo texto dentro de un elemento diferente en la misma 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))); }
Recursos adicionales
Para obtener más información sobre el uso de Espresso-Web en pruebas de Android, consulta los siguientes recursos.
Ejemplos
- WebBasicSample: Usa Espresso-Web para interactuar con objetos
WebView
.