Espresso-Intents es una extensión de Espresso que permite la validación y stubs de intents enviados por el la aplicación que se está probando. Es como Mockito, sino para Android Intents.
Si tu app delega la funcionalidad a otras apps o a la plataforma, puedes usar Espresso-Intents para que se enfoque en la lógica de tu app y asumamos que otras apps o la plataforma funcionará correctamente. Con Espresso-Intents, puedes hacer coincidir y validar tus intents salientes, o incluso proporcionar respuestas de stub en lugar respuestas de intent reales.
Cómo incluir Espresso-Intents en tu proyecto
En el archivo app/build.gradle
de tu app, agrega la siguiente línea
dependencies
Groovy
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-intents:3.6.1')
Espresso-Intents solo es compatible con Espresso 2.1+ y con la versión 0.3+ de Bibliotecas de prueba de Android, así que 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')
Cómo escribir reglas de prueba
Antes de escribir una prueba de Espresso-Intents, configura una IntentsTestRule
. Este es un
de la clase ActivityTestRule
y facilita su uso
APIs de Espresso-Intents en pruebas funcionales de la IU. Se inicializa un IntentsTestRule
Espresso-Intents antes de cada prueba anotada con @Test
y versiones
Espresso-Intents después de cada ejecución de prueba.
El siguiente fragmento de código es un ejemplo de una IntentsTestRule
:
Kotlin
@get:Rule val intentsTestRule = IntentsTestRule(MyActivity::class.java)
Java
@Rule public IntentsTestRule<MyActivity> intentsTestRule = new IntentsTestRule<>(MyActivity.class);
Coincidencia
Espresso-Intents ofrece la capacidad de interceptar intents salientes en función de determinados criterios de coincidencia, que se definen con los comparadores de Hamcrest. Hamcrest te permite hacer lo siguiente:
- Usar un comparador de intents existente: Es la opción más fácil, que casi siempre. que prefieras.
- Implementar tu propio buscador de coincidencias de intent: es la opción más flexible. Más detalles están disponibles en la sección titulada "Cómo escribir comparadores personalizados" en el Instructivo de Hamcrest.
Espresso-Intents ofrece la intended()
y intending()
para validar intents
stubbing, respectivamente. Ambos toman un objeto Matcher<Intent>
de Hamcrest como un
argumento.
El siguiente fragmento de código muestra la validación de intents que usan intents existentes comparadores que coinciden con un intent saliente que inicia un navegador:
Kotlin
assertThat(intent).hasAction(Intent.ACTION_VIEW) assertThat(intent).categories().containsExactly(Intent.CATEGORY_BROWSABLE) assertThat(intent).hasData(Uri.parse("www.google.com")) assertThat(intent).extras().containsKey("key1") assertThat(intent).extras().string("key1").isEqualTo("value1") assertThat(intent).extras().containsKey("key2") assertThat(intent).extras().string("key2").isEqualTo("value2")
Java
assertThat(intent).hasAction(Intent.ACTION_VIEW); assertThat(intent).categories().containsExactly(Intent.CATEGORY_BROWSABLE); assertThat(intent).hasData(Uri.parse("www.google.com")); assertThat(intent).extras().containsKey("key1"); assertThat(intent).extras().string("key1").isEqualTo("value1"); assertThat(intent).extras().containsKey("key2"); assertThat(intent).extras().string("key2").isEqualTo("value2");
Cómo validar intents
Espresso-Intents registra todos los intents que intentan iniciar actividades desde el
la aplicación que se está probando. Usar el método intended()
, que es similar a
Mockito.verify()
, puedes declarar que se vio un intent determinado. Sin embargo,
Espresso-Intents no elimina las respuestas a los intents, a menos que configures explícitamente
para hacerlo.
El siguiente fragmento de código es un ejemplo de prueba que valida, pero no como stub respuestas a un intent saliente que inicia un "teléfono" externo actividad:
Kotlin
@Test fun validateIntentSentToPackage() { // User action that results in an external "phone" activity being launched. user.clickOnView(system.getView(R.id.callButton)) // Using a canned RecordedIntentMatcher to validate that an intent resolving // to the "phone" activity has been sent. intended(toPackage("com.android.phone")) }
Java
@Test public void validateIntentSentToPackage() { // User action that results in an external "phone" activity being launched. user.clickOnView(system.getView(R.id.callButton)); // Using a canned RecordedIntentMatcher to validate that an intent resolving // to the "phone" activity has been sent. intended(toPackage("com.android.phone")); }
Cómo implementar stubs
Con el método intending()
, que es similar a Mockito.when()
, puedes
proporcionan una respuesta de stub para las actividades que se inician con
startActivityForResult()
Esta opción es particularmente útil para actividades externas
porque no se puede manipular la interfaz de usuario de una actividad externa ni
controlar el objeto ActivityResult
que se muestra a la actividad que se está probando.
En los siguientes fragmentos de código, se implementa un ejemplo
activityResult_DisplaysContactsPhoneNumber()
, que verifica que, cuando un elemento
el usuario inicia un "contacto" actividad en la app que estás probando, el teléfono de contacto
se muestra el siguiente número:
Compila el resultado que se mostrará cuando se inicie una actividad en particular. El la prueba de ejemplo intercepta todos los intents enviados a "contacts" y apaga su respuestas con un
ActivityResult
válido, mediante el código de resultadoRESULT_OK
Kotlin
val resultData = Intent() val phoneNumber = "123-345-6789" resultData.putExtra("phone", phoneNumber) val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)
Java
Intent resultData = new Intent(); String phoneNumber = "123-345-6789"; resultData.putExtra("phone", phoneNumber); ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData);
Indica a Espresso que proporcione el objeto de resultado de stub en respuesta a todos los invocaciones de los "contactos" intent:
Kotlin
intending(toPackage("com.android.contacts")).respondWith(result)
Java
intending(toPackage("com.android.contacts")).respondWith(result);
Verifica que la acción utilizada para iniciar la actividad produzca el resultado esperado. de stub. En este caso, la prueba de ejemplo comprueba que el número de teléfono Se muestra "123-345-6789" y que se muestra cuando la "actividad de contactos" se inicia:
Kotlin
onView(withId(R.id.pickButton)).perform(click()) onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)))
Java
onView(withId(R.id.pickButton)).perform(click()); onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)));
Esta es la prueba completa de activityResult_DisplaysContactsPhoneNumber()
:
Kotlin
@Test fun activityResult_DisplaysContactsPhoneNumber() { // Build the result to return when the activity is launched. val resultData = Intent() val phoneNumber = "123-345-6789" resultData.putExtra("phone", phoneNumber) val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData) // Set up result stubbing when an intent sent to "contacts" is seen. intending(toPackage("com.android.contacts")).respondWith(result) // User action that results in "contacts" activity being launched. // Launching activity expects phoneNumber to be returned and displayed. onView(withId(R.id.pickButton)).perform(click()) // Assert that the data we set up above is shown. onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber))) }
Java
@Test public void activityResult_DisplaysContactsPhoneNumber() { // Build the result to return when the activity is launched. Intent resultData = new Intent(); String phoneNumber = "123-345-6789"; resultData.putExtra("phone", phoneNumber); ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData); // Set up result stubbing when an intent sent to "contacts" is seen. intending(toPackage("com.android.contacts")).respondWith(result); // User action that results in "contacts" activity being launched. // Launching activity expects phoneNumber to be returned and displayed. onView(withId(R.id.pickButton)).perform(click()); // Assert that the data we set up above is shown. onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber))); }
Recursos adicionales
Para obtener más información sobre el uso de Espresso-Intents en las pruebas de Android, consulta los siguientes recursos.
Ejemplos
- IntentsBasicSample:
Uso básico de
intended()
yintending()
- IntentsAdvancedSample: Simula a un usuario que obtiene un mapa de bits con la cámara.