En este post veremos como realizar tests de UI con Espresso y con esto cerraremos la serie de artículos sobre la implementación de TDD en Android.
Recordemos que hasta el momento hemos visto como configurar nuestro proyecto para implementar TDD en el artículo “¿Cómo hacer TDD en Android? Parte 1 – Resumen y configuración“, como realizar los tests unitarios en “¿Cómo hacer TDD en Android? Parte 2 – Tests Unitarios” y cómo realizar mocking y realizar los tests de integración en “¿Cómo hacer TDD en Android? Parte 3 – Mocking & Tests de Integración“.
En este post veremos como realizar tests de UI con Espresso, pero…
¿Qué es Espresso?
Espresso es un framework de Google para testear UI, nos provee de una API probar la UI en una aplicación simple. Estos tests de UI nos dan la oportunidad de probar la parte gráfica sin necesidad de intervención del usuario.
Espresso nos proporciona básicamente tres objetos:
- ViewMatcher: usado para localizar la vista en la UI usando onView().
- ViewActions: para simular acciones sobre las vistas mediante ViewInteraction.perform().
- ViewAssertion: usado para verificar una vista usando ViewAssertion.check().
onView(withId(R.id.my_view))// withId(R.id.my_view) es un ViewMatcher .perform(click()) // click() es un ViewAction .check(matches(isDisplayed())); // matches(isDisplayed()) es un ViewAssertion
Puedes encontrar información sobre Espresso en el sitio oficial mediante el siguiente enlace: https://developer.android.com/training/testing/espresso/cheat-sheet.html
¿Cómo implementarlo?
Lo primero es asegurarnos que tenemos instanciando Espresso en nuestro proyecto, para ello en nuestro gradle tendremos que tener algo parecido a lo siguiente:
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' })
Una vez verificado creamos un nuevo test para la clase LoginActivity, LoginActivityTest.
@RunWith(AndroidJUnit4.class) public class LoginActivityTest { }
Empezaremos escribiendo el test checkUserNameEditTextIsDisplayed con la anotación @Test, para ello necesitamos un ActivityTestRule.
ActivityTestRule<LoginActivity> activityTestRule = new ActivityTestRule<>(LoginActivity.class);
En este test lo que haremos será comprobar que el campo txt_user_name se muestra:
@Test public void checkUserNameEditTextIsDisplayed() { activityTestRule.launchActivity(new Intent()); onView(withId(R.id.txt_user_name)).check(matches(isDisplayed())); }
Si ejecutamos el test veremos como se pasa correctamente. Hay que tener en cuenta que para realizar los tests de UI necesitamos un dispositivo físico o un emulador.
A continuación realizarmos el test checkPasswordEditTextIsDisplayed para verificar si el campo de contraseña se muestra.
@Test public void checkPasswordEditTextIsDisplayed() { activityTestRule.launchActivity(new Intent()); onView(withId(R.id.txt_password)).check(matches(isDisplayed())); }
Si en lugar de comprobar si se muestra comprobamos que está oculto y ejecutamos el test veremos como se marca como fallo.
El siguiente test que realizaremos será verificar que se muestra el mensaje cuando dejamos todos los campos en blanco y pulsamos el botón de login.
@Test public void checkErrorMessageIsDisplayedForEmptyData() { activityTestRule.launchActivity(new Intent()); onView(withId(R.id.btn_login)).check(matches(isDisplayed())).perform(click()); onView(withText(R.string.error_user_password)).check(matches(isDisplayed())); }
Y por último si logramos un login correcto:
@Test public void checkLoginSuccess() { activityTestRule.launchActivity(new Intent()); onView(withId(R.id.txt_user_name)).perform(typeText("user"),closeSoftKeyboard()); onView(withId(R.id.txt_password)).perform(typeText("password"),closeSoftKeyboard()); onView(withId(R.id.btn_login)).check(matches(isDisplayed())).perform(click()); onView(withText(R.string.login_ok)).check(matches(isDisplayed())); }
¡Pues con esto ya tenemos terminado nuestro proyecto usando TDD! Ya lo único que queda es ponerlo en práctica en todos nuestros proyectos.
Recuerda que tienes todo el código disponible en mi repositorio de github: https://github.com/jamontes79/TDD_Ejemplo, si lo prefieres también lo tienes disponible en Kotlin: https://github.com/jamontes79/TDD_Ejemplo_Kotlin
Espero que os hayan gustado y resultado útiles, cualquier comentario que hagáis será bienvenido.
Muchas gracias.