Last Updated: 2021-08-10
Espresso es una herramienta de Android para realizar pruebas de interfaz gráfica a partir de un proyecto de Android desarrollado en Java o en Kotlin. Espresso se presenta como un API que se puede integrar en el proyecto de Android y brinda la opción de controlar e interactuar con elementos gráficos de la interfaz por medio de pruebas que corren haciendo uso de la popular librería JUnit. Este será el foco de este tutorial.
A pesar de ser un API y de estar integrada con el proyecto a nivel de código, se puede considerar una herramienta para hacer pruebas de caja negra, dado que no es necesario comprender la totalidad de la aplicación para probar su comportamiento por medio de la interfaz. Lo único necesario es conocer los identificadores o textos distintivos de los elementos gráficos. No obstante, Android Studio ofrece la posibilidad de capturar y generar pruebas de Espresso a partir de una serie de interacciones del desarrollador con su dispositivo.
Al final de este tutorial usted tendrá:
Al desarrollar este tutorial aprenderá:
Para el caso de este tutorial, usted ejecutará pruebas sobre una aplicación de ejemplo llamada Habitica. Esta aplicación permite hacer un seguimiento a tareas diarias y hábitos haciendo uso de gamificación. Es un proyecto de código abierto desarrollado por HabitRPG el cual cuenta con más de un millón de descargas desde Google Play Store.
Dado que Espresso necesita del código fuente del proyecto para funcionar, se optará por instalar la aplicación a partir del código abierto de Habitica. El código del proyecto se encuentra alojado en un repositorio de GitHub, al cual puede acceder desde el siguiente enlace: https://github.com/HabitRPG/habitica-android/tree/release. Ingrese al enlace anterior para ver el código del proyecto en la rama estable de releases. Como con todos los proyectos de GitHub, usted puede descargar los archivos del repositorio a su máquina local por varios medios.
Si lo desea, puede optar por descargar el código fuente directamente en forma de archivo .zip desde la página web del repositorio en GitHub, haciendo clic en el botón "Download Zip" del desplegable Code, el cual se ve en la siguiente imagen:
Imagen 1. Vista desplegable del botón Code
No obstante, si cuenta con GitHub Desktop, puede hacer clic en el botón Open with GitHub Desktop. Si cuenta con Git instalado localmente en su máquina, puede clonar el repositorio a un directorio local vacío por medio del comando git clone
https://github.com/HabitRPG/habitica-android.git
o por medio de la interfaz gráfica de Git. Finalmente, también puede optar por descargar el proyecto directamente con Android Studio haciendo uso de la opción Get from Version Control del menú inicial de Android Studio, la cual se muestra en la siguiente imagen:
Imagen 2. Menú de inicio de Android Studio
Tan pronto importe el proyecto en Android Studio (ya sea directamente con la opción Get from Version Control o importando manualmente con la opción Open an existing Android Studio project), podrá ver que en segundo plano se ejecuta el proceso de sincronización de archivos de Gradle, el cual muy probablemente falle en este punto. Antes de poder ejecutar Habitica desde el proyecto, usted debe ejecutar unos pasos que permitirán configurar su versión del proyecto. Estas instrucciones son indicadas en el archivo Readme.md
del repositorio, el cual puede leer en el siguiente enlace: https://github.com/HabitRPG/habitica-android/tree/release#build-instructions.
En resumen, lo que debe hacer es modificar el nombre del archivo habitica.properties.example
a habitica.properties
y el archivo habitica.resources.example
a habitica.resources
. Luego de esto, debe crear un proyecto en Firebase que utilizará para alojar los servicios de Google para Habitica y vincularlo a su aplicación, agregando el archivo google-services.json
al directorio Habitica
del proyecto. Este paso lo puede hacer siguiendo las instrucciones del siguiente enlace: https://firebase.google.com/docs/android/setup?hl=es-419. Finalmente, vuelva a ejecutar la sincronización de Gradle.
Terminar correctamente el proceso de sincronización de Gradle significa que las dependencias del proyecto fueron construidas adecuadamente y que está listo para ser ejecutado en el modo debug.
Ahora, el siguiente paso es ejecutar la aplicación para hacer una instalación en modo debug en su dispositivo físico o virtual.
Si cuenta con un dispositivo físico con el sistema operativo Android, debe asegurarse de que este tenga activas las opciones de desarrollador y que esté habilitado para la depuración con Android Debug Bridge (ADB). Para lograr esto, siga las instrucciones en el siguiente enlace: https://developer.android.com/studio/debug/dev-options.
Una vez su dispositivo esté configurado, solo debe conectarlo a su computador por medio de un cable USB. Android Studio automáticamente detectará los dispositivos conectados, pero usted también podrá verificar que ADB reconozca a su dispositivo por medio de la consola ejecutando el comando adb devices
; esto reiniciará el servidor de ADB en su computador y determinará si se puede establecer una conexión.
Por el contrario, si no cuenta con un dispositivo físico, tendrá que crear un dispositivo virtual. Este procedimiento puede requerir pasos extra según el sistema operativo, los cuales puede averiguar en el siguiente enlace: https://developer.android.com/studio/run/emulator. Por defecto, Android Studio va a mostrar al emulador como primera opción para ejecutar la aplicación, siempre y cuando exista uno.
Una vez haya establecido la conexión con el dispositivo objetivo, podrá ver el nombre del mismo en la parte superior junto a los botones de acciones rápidas. Ahora, ejecute la aplicación presionando el botón Run, con un ícono de flecha verde para compilar y ejecutar la aplicación.
En el panel "Build" de la parte inferior podrá ver un listado de acciones que comprenden esta ejecución. Gran parte de estas acciones tienen que ver con la construcción del proyecto y sus dependencias en Gradle, y se corren en segundo plano, así que puede seguir explorando el contenido de la aplicación en el Integrated Development Environment (IDE).
Luego de un tiempo, la aplicación se ejecutará en su dispositivo y podrá ver la pantalla con el logo de Habitica, un botón para registrarse y un botón para iniciar sesión, como se muestra en la siguiente imagen:
Imagen 3. Pantalla inicial con opciones de inicio de sesión de Habitica
Tenga en cuenta que este proceso puede ser largo y tomar varios minutos mientras Android Studio gestiona y descarga las dependencias requeridas y establece los requisitos del proyecto.
Antes de ejecutar la prueba es necesario que se familiarice con la aplicación de Habitica. Como se mencionó anteriormente, esta aplicación permite manejar hábitos e incluye gamificación para motivar al cumplimiento de las mismas. Es importante que reconozca las vistas principales de la aplicación para entender las funcionalidades a probar.
Abra la aplicación que instaló en el modo de depuración. Verá un splash screen y luego de que termine, verá una pantalla con instrucciones de bienvenida. Si las omite, verá una pantalla con un botón para iniciar sesión y otro para registrarse. Cree una cuenta por el medio que prefiera y siga las instrucciones que se le van indicando dentro de la aplicación para llegar a la pantalla principal donde se expone el listado de hábitos y se le presentan varias opciones relacionadas con su personaje, sus tareas diarias, los pendientes (To Do's) y las recompensas. En cada una de estas vistas, podrá crear un elemento: hábito, diaria, pendiente, recompensa. Haga clic en el botón con el signo de suma para agregar cada uno de estos elementos y reconozca los elementos del formulario. Cuando cree cada uno de estos elementos debe poder ver el resultado generado en el listado correspondiente.
Puede continuar explorando la aplicación a su ritmo para conocer más detalles. Sin embargo, en este tutorial bastará con que conozca el proceso de inicio de sesión y la creación de una tarea básica.
Ahora que conoce las particularidades de la aplicación a probar, reconozca los pasos que debe seguir para crear su primera prueba en Espresso, la cual consiste en iniciar sesión con sus nuevas credenciales, y crear un nuevo hábito con valores de prueba.
Recuerde las credenciales, ya que debe iniciar sesión con ellas para poder utilizar las funcionalidades de la aplicación. Para este ejercicio, probará únicamente las funcionalidades de inicio de sesión y validación de elementos de interfaz gráfica.
Puntualmente, los elementos gráficos con los que debe interactuar la prueba son explicados en la siguiente tabla:
Elemento correspondiente | Elemento gráfico |
Botón de opción "Login" | |
Campo de texto del nombre de usuario | |
Campo de texto de la contraseña | |
Botón de confirmación "Login" | |
Pantalla de inicio con los hábitos |
Luego de haber ejecutado la aplicación respectiva al proyecto recién creado, usted puede realizar pruebas con JUnit, a partir de las cuales puede hacer uso de Espresso.
Por defecto, los proyectos creados en Android Studio no incluyen librerías ni dependencias, y es necesario agregarlas a mano para poder utilizar las herramientas que se necesitan en la aplicación. Para utilizar Espresso en un proyecto nuevo de Android Studio, es necesario que incluya la librería de JUnit y la configure como el motor de pruebas de Android, que incluya la librería de Espresso, y el runner de pruebas de la librería support
.
En el caso de Habitica, estas dependencias ya están incluidas por parte de los desarrolladores en el proyecto, así que no debe incluirlas. No obstante, en el siguiente párrafo se incluyen las instrucciones para agregar Espresso a su aplicación.
Estas dependencias son incluidas automáticamente cuando el proyecto se elige con el API 15: Android 4.0.3 (Ice Cream Sandwich) como el nivel mínimo de SDK. No obstante, en la mayoría de casos va a ser necesario que lo incluya de forma manual. Para esto, es necesario que siga estos pasos:
build.gradle
del módulo :app en el editor de Android Studio. (En el caso de la aplicación utilizada en este proyecto se renombró el módulo a :Habitica)dependencies
. Verifique si existen las siguientes líneas de código y en caso de no existir, agréguelas:testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
defaultConfig
. Verifique si existe la siguiente línea de código y en caso de no existir, agréguela:testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
Luego de que termine el proceso de sincronización, revise si el resultado es adecuado o hubo algún error. Es posible que existan errores relacionados con su versión de Gradle o la versión de alguna de las librerías. Si este es el caso, Android Studio le ayudará a actualizarlas a las versiones adecuadas por medio de sugerencias del Lint (la herramienta de análisis estático de código de Android Studio). Así mismo, si su aplicación utiliza AndroidX, es posible que deba incluir otros pasos en la construcción del proyecto. En este caso, oriéntese por las instrucciones del siguiente enlace: https://developer.android.com/training/testing/set-up-project.
Primero revise las especificaciones y características de la librería de Espresso y las características relevantes de la librería JUnit en el siguiente enlace: https://www.tutorialspoint.com/espresso_testing/espresso_testing_quick_guide.htm. Podrá notar que para las pruebas fundamentalmente se tienen anotaciones para marcar métodos como pruebas, precondiciones, postcondiciones o reglas. Así mismo, podrá notar que Espresso permite ejecutar acciones de interacción con la interfaz por medio de Matchers y Actions, los cuales se invocan como métodos. Finalmente, podrá ver que Espresso también permite hacer aserciones para validar el contenido de la interfaz gráfica.
A continuación se hace un resumen de las características que debería conocer para utilizar la librería en sus proyectos:
| Permite ejecutar acciones una única vez antes de todos los casos de prueba. |
| Permite añadir comportamientos determinados a los escenarios de prueba que actúan de forma temporal durante cada uno individualmente. Un ejemplo de esta anotación, recurrente en proyectos con Espresso, es la declaración de un |
| Permite ejecutar acciones como precondiciones antes de cada uno de los escenarios de prueba individualmente. |
| Marca un método de Java como un escenario de prueba. Es un reemplazo del mecanismo de JUnit 3 donde se debía crear una clase que extendiera de |
| Permite ejecutar acciones como precondiciones antes de cada uno de los escenarios de prueba individualmente. |
| Permite ejecutar acciones una única vez al finalizar todos los casos de prueba. |
assertTrue(booleano), assertFalse(booleano), assertEquals(valor1, valor2), assertNull(objeto), assertNotNull(objeto), assertSame(referencia1, referencia2), assertNotSame(referencia1, referencia2)
. Como lo indican sus nombres, los métodos permiten validar el valor de verdad de una variable, comparar tanto el valor como los objetos a los que refieren un par de variables, y generar un fallo en caso de que no se cumplan las aserciones.
Así mismo, existe el método fail()
que explícitamente hace fallar un escenario de prueba.
@RunWith(AndroidJUnit4.class)
Espresso.onView(ViewMatcher)
, el cual toma como parámetro un ViewMatcher para identificar la vista.perform()
de las ViewInteractions.check()
de las ViewInteractions.Para ahondar en los detalles de la librería Espresso, recuerde revisar el enlace del primer párrafo de este paso. Allí podrá ver el listado de Interactions, Matchers, Actions y Assertions que puede utilizar en sus aplicaciones de Android.
Ahora que reconoce los pasos que va a ejecutar en la prueba, proceda a crear el archivo con el código de la prueba. Si no existe todavía, cree el directorio Habitica/src/androidTest/java/com.habitrpg.android.habitica.ui.activities
de forma manual y cree un archivo allí con la prueba (con el nombre Test1Habitica y la extensión .java
). Dentro de dicho archivo cree el contenido de la prueba a partir de la documentación del enlace de Espresso. Tendrá que tener algo parecido al siguiente código:
import androidx.test.espresso.ViewInteraction; import androidx.test.filters.LargeTest; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; import com.habitrpg.android.habitica.R; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; import static androidx.test.espresso.action.ViewActions.replaceText; import static androidx.test.espresso.action.ViewActions.scrollTo; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; @LargeTest @RunWith(AndroidJUnit4.class) public class MainActivityTest2 { @Rule public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class); @Test public void mainActivityTest2() { ViewInteraction skipBtn = onView(allOf(withId(R.id.skipButton), withText("Skip"),isDisplayed())); skipBtn.perform(click()); ViewInteraction loginBtn = onView(allOf(withId(R.id.show_login_button), withText("Login"),isDisplayed())); loginBtn.perform(click()); ViewInteraction usernameTxt = onView(withId(R.id.username)); usernameTxt.perform(scrollTo(), replaceText("monbi202010@gmail.com"), closeSoftKeyboard()); ViewInteraction pwdTxt = onView(withId(R.id.password)); pwdTxt.perform(scrollTo(), replaceText("123456789MISO"), closeSoftKeyboard()); ViewInteraction confirmLoginBtn = onView(allOf(withId(R.id.login_btn), withText("Login"))); confirmLoginBtn.perform(scrollTo(), click()); } }
Note que la prueba únicamente consiste en una clase con las anotaciones @LargeTest
y @RunWith
. Sus propiedades contienen únicamente un atributo del tipo ActivityTestRule con la anotación @Rule
para permitir a la prueba identificar la Activity que se va a desplegar y sobre la cual se van a ejecutar las acciones; y un método con la anotación @Test,
el cual contiene las instrucciones para interactuar con la interfaz gráfica. Estas instrucciones funcionan gracias al método perform
de los objetos ViewInteraction. Así mismo, note que los Views de la interfaz se obtienen a partir del objeto R, utilizando el identificador definido en el archivo .xml
de layout para cada una de ellas, o bien utilizando una característica distintiva como el texto y el hecho de estar mostrado en la interfaz.
La prueba debería funcionar con el código acá incluido. No obstante, es ideal que reemplace los textos de las credenciales por los de las credenciales de la cuenta que usted creó en un paso anterior. Así mismo, es importante recordar que esta prueba asume como precondición que en la aplicación no existe una sesión ya iniciada y almacenada localmente, por lo cual, si usted ha estado utilizando la aplicación, se recomienda que cierre sesión, ya sea de forma manual antes de ejecutar la prueba o incluyendo los pasos requeridos en la prueba de Espresso.
Android Studio guarda automáticamente los archivos que usted edita en el IDE. Ahora que modificó el contenido del archivo de su prueba, va a ejecutar la prueba. Para esto, en el panel lateral izquierdo del explorador de archivos busque el archivo que acaba de crear con la prueba y haga clic derecho sobre él y desplegará un menú con varias opciones como el que se muestra en la siguiente imagen:
Imagen 4. Menú desplegado al hacer clic derecho sobre el archivo de prueba
Haga clic en la opción Run de su prueba para ejecutarla en el dispositivo o emulador Android que tenga conectado al computador. Podrá ver que en su dispositivo aparecen las pantallas de la aplicación de Habitica en una ráfaga rápida, donde es difícil reconocer todo lo que está sucediendo. Cuando termine la prueba podrá ver los resultados en la parte inferior de Android Studio, donde se indica el número de pruebas ejecutadas y finalizadas exitosamente, como se muestra en la siguiente imagen:
Imagen 5. Panel con los resultados de la prueba
¡Felicidades!
Al finalizar este tutorial, pudo familiarizarse con el entorno del desarrollo de aplicaciones en Android haciendo uso de las herramientas de Android Studio y el lenguaje de programación Kotlin.
Ahora podrá crear sus propios proyectos de Android, compilar y ejecutar aplicaciones y ahondar en las particularidades del desarrollo con Kotlin para crear aplicaciones modernas y cada vez más complejas.
Juan Sebastián Espitia Acero | Autor |
Norma Rocio Héndez Puerto | Revisora |
Mario Linares Vásquez | Revisor |