Patrones comunes

Puedes probar tu app de Compose con enfoques y patrones 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 te recomendamos que verifiques que los elementos componibles estén encapsulados correctamente y funcionen de forma independiente, lo que permite realizar pruebas de IU más fáciles y enfocadas.

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, necesitas configurar el contenido que se prueba con composeTestRule.setContent y también debes acceder a los recursos de la actividad, 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 usando 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 eso, 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 nuevo SemanticsPropertyKey y haz que esté disponible mediante 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 esas verificaciones sin depender de la recreación de 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.
    }
}

Cómo probar 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, y mucho más. La mayoría de estas condiciones derivan de los valores a nivel del dispositivo controlados por el usuario y se exponen con la instancia de Configuration actual. 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 de solo prueba que te permite simular diferentes configuraciones de dispositivos de manera localizada para el contenido de @Composable en prueba.

El objeto complementario de DeviceConfigurationOverride tiene las siguientes funciones de extensión, que anulan 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 fuerza que el elemento MyScreen componible se renderice en una ventana horizontal grande, incluso si el dispositivo en el que se ejecuta la prueba no admite directamente ese tamaño de ventana:

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 conceptos 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 apps para Android.
  • Pruebas locales: Puedes ejecutar algunas pruebas de forma local en tu propia estación de trabajo.
  • Pruebas instrumentadas: se recomienda ejecutar también pruebas de instrumentación. 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 algunos 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.