Patrones comunes

Puedes probar tu app de Compose con enfoques y patrones bien establecidos.

Prueba aislada

ComposeTestRule te permite iniciar una actividad que muestre elementos componibles: tu aplicación completa, una sola pantalla o un elemento pequeño. También se recomienda comprobar que los elementos que admiten composición estén bien encapsulados y funcionen de manera independiente para poder probar las IU de forma más fácil y precisa.

Eso no significa que solo deberías crear pruebas de IU por unidad. También son muy importantes las pruebas de IU que abarcan partes más grandes de ella.

Cómo acceder a la actividad y a los recursos después de configurar tu propio contenido

A menudo, debes configurar el contenido que se prueba con composeTestRule.setContent y también debes acceder a los recursos de las actividades, por ejemplo, para afirmar que un texto que se muestra coincide con un recurso de cadenas. Sin embargo, no puedes llamar a setContent en una regla creada con createAndroidComposeRule() si la actividad ya la llama.

Un patrón común para lograr esto es crear un AndroidComposeTestRule con una actividad vacía, como ComponentActivity.

class MyComposeTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule<ComponentActivity>()

    @Test
    fun myTest() {
        // Start the app
        composeTestRule.setContent {
            MyAppTheme {
                MainScreen(uiState = exampleUiState, /*...*/)
            }
        }
        val continueLabel = composeTestRule.activity.getString(R.string.next)
        composeTestRule.onNodeWithText(continueLabel).performClick()
    }
}

Ten en cuenta que ComponentActivity debe agregarse al archivo AndroidManifest.xml de tu app. Para habilitar esta función, agrega esta dependencia a tu módulo:

debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")

Propiedades semánticas personalizadas

Puedes crear propiedades de semántica personalizadas para exponer información a las pruebas. Para ello, define un SemanticsPropertyKey nuevo y haz que esté disponible con SemanticsPropertyReceiver.

// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey

Ahora, usa esa propiedad en el modificador semantics:

val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
    modifier = Modifier.semantics { pickedDate = datePickerValue }
)

En las pruebas, usa SemanticsMatcher.expectValue para confirmar el valor de la propiedad:

composeTestRule
    .onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
    .assertExists()

Cómo verificar el restablecimiento del estado

Verifica que el estado de tus elementos de Compose se restablezca correctamente cuando se vuelva a crear la actividad o el proceso. Realiza estas verificaciones sin depender de la recreación de la actividad con la clase StateRestorationTester.

Esta clase te permite simular la recreación de un elemento que admite composición. Es especialmente útil para verificar la implementación de rememberSaveable.


class MyStateRestorationTests {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun onRecreation_stateIsRestored() {
        val restorationTester = StateRestorationTester(composeTestRule)

        restorationTester.setContent { MainScreen() }

        // TODO: Run actions that modify the state

        // Trigger a recreation
        restorationTester.emulateSavedInstanceStateRestore()

        // TODO: Verify that state has been correctly restored.
    }
}

Prueba diferentes configuraciones de dispositivos

Las apps para Android deben adaptarse a muchas condiciones cambiantes: tamaños de ventana, configuraciones regionales, tamaños de fuente, temas oscuros y claros, entre otros. La mayoría de estas condiciones se derivan de valores a nivel del dispositivo que controla el usuario y se exponen con la instancia actual de Configuration. Probar diferentes configuraciones directamente en una prueba es difícil, ya que la prueba debe configurar propiedades a nivel del dispositivo.

DeviceConfigurationOverride es una API solo para pruebas que te permite simular diferentes configuraciones de dispositivos de forma localizada para el contenido @Composable en prueba.

El objeto complementario de DeviceConfigurationOverride tiene las siguientes funciones de extensión, que anula las propiedades de configuración a nivel del dispositivo:

Para aplicar una anulación específica, une el contenido que se está probando en una llamada a la función de nivel superior DeviceConfigurationOverride() y pasa la anulación para aplicarla como parámetro.

Por ejemplo, el siguiente código aplica la anulación DeviceConfigurationOverride.ForcedSize() para cambiar la densidad de forma local, lo que obliga a que el elemento componible MyScreen se renderice en una ventana horizontal grande, incluso si el dispositivo en el que se ejecuta la prueba no admite ese tamaño de ventana directamente:

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
    }
}

Para aplicar varias anulaciones a la vez, usa DeviceConfigurationOverride.then():

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.FontScale(1.5f) then
            DeviceConfigurationOverride.FontWeightAdjustment(200)
    ) {
        Text(text = "text with increased scale and weight")
    }
}

Recursos adicionales

  • Cómo probar apps en Android: La página de destino principal de pruebas de Android proporciona una vista más amplia de los aspectos básicos y las técnicas de prueba.
  • Aspectos básicos de las pruebas: Obtén más información sobre los conceptos básicos de las pruebas de una app para Android.
  • Pruebas locales: Puedes ejecutar algunas pruebas de manera local en tu propia estación de trabajo.
  • Pruebas instrumentadas: Se recomienda ejecutar pruebas instrumentadas. Es decir, pruebas que se ejecutan directamente en el dispositivo.
  • Integración continua: La integración continua te permite integrar tus pruebas en la canalización de implementación.
  • Prueba diferentes tamaños de pantalla: Con muchos dispositivos disponibles para los usuarios, debes probar diferentes tamaños de pantalla.
  • Espresso: Si bien está diseñado para las IU basadas en View, el conocimiento de Espresso puede ser útil para algunos aspectos de las pruebas de Compose.