Table of Contents
Como mobile developers, pasamos la mayor parte de tiempo creando nuevas pantallas o cambiando pantallas que ya existen y necesitamos saber que el código funciona. Es por eso que en nuestro proceso de desarrollo debemos utilizar herramientas para verificar que nuestra aplicación sigue funcionando como esperamos y que nuestro desarrollo cumple con la calidad del producto deseada según la historia de usuario. En este artículos trataremos el Espresso UI Test.
Asegurarnos que:
- Mostramos la información correcta al usuario cuando la UI está cargada
- Mostrar el mensaje o pantalla deseada dada una acción del usuario
Para cumplir con este objetivo existen varios tipos de test de ui:
- Classic ui testing -> se enfoca en vistas y sus interacciones.
- Snapshot testing -> garantiza el diseño perfecto, dejando a un lado las interacciones.
¿ Que es Espresso UI Test? ¿Como funciona?
Espresso es un framework creado por Google para Android que nos permite escribir test sobre la interfaz de usuario.
Dispone de una simple API, fácil de adaptar a nuestras necesidades y elimina la complejidad de la gestión de distintos hilos de ejecución.
Espresso UI Test funciona basicamente en tres bloques:
- ViewMatchers – permite encontrar un elemento en la vista
- ViewActions – permite ejecutar acciones sobre los elementos
- ViewAssertions – valida un estado de la vista
Trabajando con espresso es recomendable tener esta hoja cerca.
Configuración
Para qué espresso funcione en nuestro proyecto necesitamos agregar la dependencias en nuestro archivo ‘app/build.gradle’ y un dispositivo físico o virtual.
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
// Android runner and rules support
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
// Espresso
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
Es recomendable apagar la animaciones de nuestro dispositivo android que utilizaremos para los test en las opciones de desarrollador. Una forma fácil de hacerlo es ejecutando estos comandos desde tu terminal:
adb shell settings put global window_animation_scale 0.0
adb shell settings put global transition_animation_scale 0.0
adb shell settings put global animator_duration_scale 0.0
Implementación
Como pequeño ejercicio práctico hemos creado una vista con dos textviews y un botón donde queremos evaluar que cuando presionemos el botón se esconda un textview y se muestre otro.
Podemos crear nuestro test ui de forma automática mediante la herramienta récord de espresso o manualmente.
- Record Espresso
Para ello debemos ir en la barra de opciones de android studio a Run -> Record Espresso Test
Nos lanzará una pantalla donde podemos ir haciendo aserciones
Y al terminar nos generará el código del test:
@LargeTest
@RunWith(AndroidJUnit4.class)
public class RecordedTextViewToggleVisibilityTest {
@Rule
public ActivityTestRule mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void textViewToggleVisibilityTest() {
ViewInteraction textView = onView(
allOf(withId(R.id.tv_hello), withText("Hello buddy!"),
childAtPosition(
childAtPosition(
withId(android.R.id.content),
0),
0),
isDisplayed()));
textView.check(matches(withText("Hello buddy!")));
ViewInteraction appCompatButton = onView(
allOf(withId(R.id.button), withText("click me"),
childAtPosition(
childAtPosition(
withId(android.R.id.content),
0),
2),
isDisplayed()));
appCompatButton.perform(click());
ViewInteraction textView2 = onView(
allOf(withId(R.id.tv_see_you), withText("See you"),
childAtPosition(
childAtPosition(
withId(android.R.id.content),
0),
1),
isDisplayed()));
textView2.check(matches(isDisplayed()));
}
private static Matcher childAtPosition(
final Matcher parentMatcher, final int position) {
return new TypeSafeMatcher() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}
@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
}
- Forma manual
@LargeTest
@RunWith(AndroidJUnit4.class)
public class ManualTextViewToggleVisibilityTest {
@Rule
public ActivityTestRule mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void textViewToggleVisibilityTest() {
// here we are going to look in the view tree
// we use allOff from hamcrest library to combine matchers
ViewInteraction tvHello = onView(allOf(withId(R.id.tv_hello),withText(R.String.hello_buddy)));
ViewInteraction tvSeeYou = onView(allOf(withId(R.id.tv_see_you),withText(R.String.see_you)));
// assert that textView with text 'Hello buddy!' is display
tvHello.check(matches(isDisplayed()));
// assert that textView with text 'See you' has visibility gone
tvSeeYou.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
// find button with given id and click
onView(withId(R.id.button)).perform(click());
// assert see you is visible and hello buddy is not. tvHello.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
tvSeeYou.check(matches(isDisplayed()));
}
}
Podemos comprobar que Espresso de forma automática nos ha generado mas codigo, el cual se puede romper fácilmente y necesitará un mayor mantenimiento. Por ejemplo a utilizado el string literal para encontrar la vista y en caso de cambiar el idioma al dispositivo el test fallaría, sin embargo de forma manual podemos utilizar el id del string resource y agregar tantos matchers como necesitemos.
Esta guía de referencia hamcrest te puede ser útil a la hora de trabajar con matchers.
Conclusión
Como humanos somos propensos a cometer errores y esto implica que nuestro software sea vulnerable a bugs y defectos. Espresso nos ayuda a detectar los errores que se puedan haber cometido en el desarrollo asegurando la confiabilidad del Cliente y su satisfacción con la aplicación.
Si aún no has agregado Espresso a tus herramientas de desarrollo piensa en las personas que tendrán que probar la aplicación manualmente.
Suscríbete a nuestro newsletter para estar al día de Espresso UI Test !
Si este artículo sobre Espresso UI Test te gustó, te puede interesar:
Tendencias en aplicaciónes móviles
Debugging con Charles Proxy en Android emulator
Integración Continua en iOS usando Fastlane y Jenkins
Meetups de arquitectura de software
More to Explore