Las actividades funcionan como contenedores de 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 a 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 de manera correcta 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 a medida que las actividades de la app pasan por los diferentes estados en sus ciclos de vida.
Cómo administrar el estado de una actividad
Un aspecto clave a la hora de probar las actividades de tu app implica colocar las actividades de tu app en estados particulares. Para definir esta parte "determinada" de tus pruebas, usa instancias de ActivityScenario
, que forma parte de la biblioteca de 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 de integración en el dispositivo. En un dispositivo real o virtual, ActivityScenario
proporciona seguridad para los subprocesos y sincroniza eventos entre el subproceso de instrumentación de tu prueba y el subproceso que ejecuta la actividad que se está probando.
La API es particularmente adecuada para evaluar cómo se comporta una actividad que se está probando cuando se crea o se destruye. En esta sección, se presentan los casos de uso más comunes asociados con esta API.
Crea 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 { } } }
Después de crear la actividad, ActivityScenario
hace la transición de esta al estado RESUMED
. Este estado indica que tu actividad está en ejecución y que los usuarios pueden verla. En este estado, puedes interactuar con los elementos View
de tu actividad mediante 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 las 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.
Como alternativa, puedes usar ActivityScenarioRule
para llamar automáticamente a ActivityScenario.launch
antes de cada prueba y ActivityScenario.close
en la desconexión de la prueba. En el siguiente ejemplo, se muestra cómo definir una regla y obtener de ella una instancia de una situación:
@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 llevar 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 una 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 redirecciona 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, el sistema puede destruir una actividad y requerir que tu app la vuelva a crear 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 anotado con @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 estás probando, usa los comparadores de vistas de Espresso a fin de interactuar con los elementos de 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 forma segura implementando ActivityAction
:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> activity.handleSwipeToRefresh() } } } }