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:
DeviceConfigurationOverride.DarkMode()
: Anula el sistema para el tema oscuro o el tema claro.DeviceConfigurationOverride.FontScale()
: Anula la escala de la fuente del sistema.DeviceConfigurationOverride.FontWeightAdjustment()
: Anula el ajuste del grosor de la fuente del sistema.DeviceConfigurationOverride.ForcedSize()
: Fuerza una cantidad específica de espacio, independientemente del tamaño del dispositivo.DeviceConfigurationOverride.LayoutDirection()
: Anula la dirección del diseño (de izquierda a derecha o de derecha a izquierda).DeviceConfigurationOverride.Locales()
: Anula la configuración regional.DeviceConfigurationOverride.RoundScreen()
: Se anula si la pantalla es redondo.
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.