Espresso (framework)
# Espresso (framework)

Espresso es un framework de testing open source lanzado por Google el cual provee una API que permite crear pruebas de interfaz de usuario (de ahora en adelante UI por sus siglas en inglés) para simular interacciones de usuarios en una aplicación Android (en la versión 2.2 en adelante). Es una buena práctica simular los diferentes escenarios en los que el usuario puede interactuar con una aplicación para evitar que este se encuentre con resultados inesperados o bien tenga una mala experiencia al momento de su uso. Es por esta razón que es recomendable la creación de un entorno de pruebas vinculadas a la UI con el fin de asegurarnos que la aplicación está funcionando correctamente.

Su principal ventaja es que nos permite la sincronización automática de las acciones de las pruebas con la interfaz de usuario de nuestra aplicación. Además, permite la ejecución de pruebas en máquinas x86 en un ambiente multihilo, solucionando problemas de concurrencia asociados al testing de UI.

Espresso permite realizar pruebas tanto en dispositivos físicos como virtuales (emuladores).La principal desventaja de ejecutar las pruebas en dispositivos físicos (reales) se debe a su alto costo y tiempo que requiere por la gran variedad de dispositivos existentes en la actualidad. Una posible solución es ejecutar estas pruebas en un emulador (ambiente controlado que permite soportar múltiples versiones de SO, tamaños de pantalla y limitantes de memoria).

A modo de ejemplo, si comparamos la velocidad de ejecución de las pruebas en un Nexus 4 contra un emulador, este último requiere un 65% menos de tiempo para llevarla a cabo. De acuerdo al equipo de trabajo detrás de Espresso, su solución logró detectar el 99% de los bugs en las aplicaciones Android, dejando unos pocos para las pruebas tradicionales (reduciendo el esfuerzo requerido para las mismas).

## Ejemplo

Para realizar las pruebas se debe crear una clase Java que contenga los tests dentro de los cuales se realizarán las siguientes acciones:

* Encontrar el componente que se desea probar en un Activity (por ejemplo un botón en la aplicación) invocando al método onView
* Simular una acción del usuario invocando al método ViewInteraction.perform y pasando la acción que realizó (por ejemplo un click sobre un botón). En caso de querer simular múltiples acciones sobre el mismo componente concatenarlos separados por "," en el argumento del método
* Repetir estos pasos con el fin de simular múltiples actividades en la aplicación
* Utilizar los métodos de ViewAssertions para chequear que la interfaz de usuario responde con el comportamiento esperado.

Tres componentes son los que conforman al framework, permitiendo:

* ViewMatchers: ubicar una vista dentro de las jeraruía de vista actual ("Buscar algo")
* ViewActions: interactuar con las vistas ("Hacer algo")
* ViewAssertions: asegurar el estado de una vista ("Chequar algo")

Supongamos que tenemos una aplicación donde se le solicita al usuario que ingrese su nombre. Luego, es necesario que este presione el botón de "Siguiente" donde irá a otra pantalla donde aparecerá su presentación con su respectivo nombre.

### ¿Cómo realizar pruebas para este escenario?

IMPORTANTE: Como se observó en el ejemplo anterior, no es necesario especificar con qué tipo de vista estamos interactuando (EditText, Button, etc), simplemente ingresamos el id de la vista.

Además, al hacer click sobre el botón "Siguiente", no es necesario especificar al framework que navegue hacia la otra pantalla.

## Comparación

### Robotium

Sin lugar a dudas este framework fue el más utilizado en las primeras apariciones en el mundo Android. En comparación con Selenium en Android, este hace la API de testing mucho más simple. Robotium es una librería open source que extiende de JUnit con una gran cantidad de métodos que pueden ser utilizados para pruebas de interfaz de usuario en dispositivos Android. Este provee, además, un amplio conjunto de casos de prueba de caja negra automáticos que se caracterizan por ser robustos y potentes para aplicaciones Android (nativas, híbridas y web)

### uiautomator

Mientras Robotium es un framework de testing básico, este nos permite hacer más pruebas en aplicaciones y juegos desarrollados en Android. Otra de las ventajas de este framework es que ejecuta casos de prueba JUnit con privilegios especiales, lo que permite que las casos de prueba puedan extenderse a través de los diferentes procesos. Incluye cinco clases para que sean utilizados por los desarrolladores:

* com.android.uiautomator.core.UiCollection;
* com.android.uiautomator.core.UiDevice;
* com.android.uiautomator.core.UiObject;
* com.android.uiautomator.core.UiScrollable;
* com.android.uiautomator.core.UiSelector

Cabe destacar que solo funciona para dispositivos Android cuyo API level sea mayor a 16

### Espresso

Es el último framework open source propusto por Google para la automatización de pruebas para Android con el fin que tanto los desarrolladores como testers puedan probar sus propias interfaces. Este tiene una API que se caracteriza por ser pequeña, predicible y fácil de aprender. Este es soportado por un API level 8 (Froyo), 10 (Gingerbread), y 15 (Ice Cream Sandwich), y los siguientes.

### Appium

Es un framework de automatización de pruebas para aplicaciones web y mobile tanto en forma nativa como híbrida para iOS y Android. Internamente utiliza JSONWireProtocol para intereactuar con las aplicaciones iOS y Android utilizando Selenium’s WebDriver.

Soporta:

* Android via uiautomator (API level 16 o mayor) y Seledroid (API level menor que 16)
* iOS: via Automation
* mobile Web via Selenium driver para Android e iOS

La ventaja principal es que permite escribir los scripts en casi cualquier lenguaje de programación, por ejemplo Java, Objective-C, , JavaScript, PHP, Ruby, Python or C#, etc)

### Calabash

Nos permite automatizar las pruebas para aplicaciones en iOS y Android tanto en forma nativa como híbrida. Su principal ventaja se encuentra en la facilidad para entender la sintaxis, permitiendo así que personas no técnicas puedan crear y ejecutar sus propias pruebas. Soporta aproximadamente 80 controladores y los nuevos pueden ser implementados en Ruby o Java.

