Las actividades sirven como contenedores para cada interacción del usuario dentro de tu app, por lo que es importante probar cómo se comportan las actividades de tu app durante los eventos en el nivel del dispositivo, como los siguientes:
- Otra app, como la app de teléfono del dispositivo, interrumpe la actividad de tu app.
- El sistema elimina y vuelve a crear tu actividad.
- El usuario coloca tu actividad en un nuevo entorno de ventanas, como pantalla en pantalla (PIP) o el modo multiventana.
En particular, es importante que te asegures de que tu actividad se comporte correctamente en respuesta a los eventos descritos en El ciclo de vida de la actividad.
En esta guía, se describe cómo evaluar la capacidad de tu app para mantener la integridad de los datos y una buena experiencia del usuario mientras las actividades de tu app cambian de estado en sus ciclos de vida.
Cómo administrar el estado de una actividad
Un aspecto clave al probar las actividades de tu app es colocarlas en estados particulares. Para definir esta parte "dada" de tus pruebas, usa instancias de ActivityScenario, que forma parte de la biblioteca AndroidX Test. Con esta clase, puedes colocar tu actividad en estados que simulan eventos a nivel del dispositivo.
ActivityScenario es una API multiplataforma que puedes usar tanto en las pruebas de unidades locales como en las pruebas de integración en el dispositivo. En un dispositivo real o virtual, ActivityScenario proporciona seguridad para los subprocesos, sincronización de eventos entre el subproceso de instrumentación de tu prueba y el subproceso que ejecuta la actividad que estás probando.
La API es particularmente adecuada para evaluar cómo se comporta una actividad que se está probando cuando se crea o se elimina. En esta sección, se presentan los casos de uso más comunes asociados con esta API.
Cómo crear una actividad
Para crear la actividad que se está probando, agrega el código que se muestra en el siguiente fragmento:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { } } }
Una vez que la crees, ActivityScenario pasará la actividad al estado RESUMED. Este estado indica que tu actividad se está ejecutando y es visible para los usuarios. En este estado, puedes interactuar con los elementos View de tu actividad con las pruebas de IU Espresso.
Google recomienda que llames a close en la actividad cuando se complete la prueba. Esto limpia los recursos asociados y mejora la estabilidad de tus pruebas. ActivityScenario implementa Closeable, por lo que puedes aplicar la extensión use o try-with-resources en el lenguaje de programación Java para que la actividad se cierre automáticamente.
De manera alternativa, puedes usar ActivityScenarioRule para llamar automáticamente a ActivityScenario.launch antes de cada prueba y a ActivityScenario.close en la desconexión de la prueba. En el siguiente ejemplo, se muestra cómo definir una regla y obtener una instancia de una situación de esta:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>() @Test fun testEvent() { val scenario = activityScenarioRule.scenario } }
Cómo pasar la actividad a un nuevo estado
Para pasar la actividad a un estado diferente, como CREATED o STARTED, llama a moveToState(). Esta acción simula una situación en la que tu actividad se detiene o se pausa, respectivamente, porque otra app o acción del sistema la interrumpe.
En el siguiente fragmento de código, se muestra un ejemplo del uso de moveToState():
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.moveToState(State.CREATED) } } }
Cómo determinar el estado actual de la actividad
Para determinar el estado actual de una actividad que se está probando, obtén el valor del campo state dentro de tu objeto ActivityScenario. Es particularmente útil comprobar el estado de una actividad que se está probando si esta redirige a otra actividad o se finaliza a sí misma, como se muestra en el siguiente fragmento de código:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> startActivity(Intent(activity, MyOtherActivity::class.java)) } val originalActivityState = scenario.state } } }
Cómo volver a crear la actividad
Cuando un dispositivo tiene pocos recursos, es posible que el sistema destruya una actividad, lo que significa que tu app deberá volver a crearla cuando el usuario regrese a ella. Para simular estas condiciones, llama a recreate():
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.recreate() } } }
La clase ActivityScenario mantiene el estado de la instancia guardada de la actividad y cualquier objeto con anotaciones mediante @NonConfigurationInstance. Estos objetos se cargan en la nueva instancia de la actividad que estás probando.
Cómo obtener los resultados de la actividad
Para obtener el código de resultado o los datos asociados con una actividad finalizada, obtén el valor del campo result dentro de tu objeto ActivityScenario, como se muestra en el siguiente fragmento de código:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testResult() { launchActivity<MyActivity>().use { onView(withId(R.id.finish_button)).perform(click()) // Activity under test is now finished. val resultCode = scenario.result.resultCode val resultData = scenario.result.resultData } } }
Cómo activar acciones en la actividad
Todos los métodos dentro de ActivityScenario son llamadas de bloqueo, por lo que la API requiere que los ejecutes en el subproceso de instrumentación.
Para activar acciones en la actividad que se está probando, usa los comparadores de vista de Espresso a fin de interactuar con elementos en tu vista:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { onView(withId(R.id.refresh)).perform(click()) } } }
Sin embargo, si necesitas llamar a un método en la actividad, puedes hacerlo de manera segura implementando ActivityAction:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> activity.handleSwipeToRefresh() } } } }