Cómo probar las actividades de tu app

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 su 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 Información sobre 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 de tus pruebas, usa instancias de ActivityScenario, que forma parte de la biblioteca Pruebas de AndroidX. Al usar esta clase, puedes colocar tu actividad en estados que simulan los eventos en el nivel del dispositivo que se describen al comienzo de esta página.

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 también 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 prácticos 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() {
            val scenario = launchActivity<MyActivity>()
        }
    }
    

Una vez que la crees, ActivityScenario pasará la actividad al estado RESUMED, que 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.

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() {
            val scenario = launchActivity<MyActivity>()
            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() {
            val scenario = launchActivity<MyActivity>()
            scenario.onActivity { activity ->
              startActivity(Intent(activity, MyOtherActivity::class.java))
            }

            val originalActivityState = scenario.state
        }
    }
    

Cómo volver a crear la actividad

Si un dispositivo tiene pocos recursos, es posible que el sistema elimine 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() {
            val scenario = launchActivity<MyActivity>()
            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 ver el código de resultado o los datos asociados con una actividad finalizada, debes obtener 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() {
            val scenario = launchActivity<MyActivity>()
            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 un 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() {
            val scenario = launchActivity<MyActivity>()
            onView(withId(R.id.refresh)).perform(click())
        }
    }
    

Sin embargo, si necesitas llamar a un método en la actividad, puedes hacerlo de manera segura mediante la implementación de ActivityAction:

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            scenario.onActivity { activity ->
              activity.handleSwipeToRefresh()
            }
        }
    }
    

Para obtener más información sobre cómo funcionan los subprocesos en las pruebas de Android, consulta Información sobre los subprocesos en pruebas.