Las pruebas de Compose se sincronizan de forma predeterminada con tu IU. Cuando llamas a una
aserción o una acción con ComposeTestRule, la prueba se sincroniza
antes y se espera hasta que el árbol de IU esté inactivo.
Normalmente, no es necesario que realices ninguna acción. Sin embargo, hay algunos casos extremos que debes conocer.
Cuando se sincroniza una prueba, tu app de Compose está avanzada a tiempo con un reloj virtual. Eso significa que las pruebas de Compose no se ejecutan en tiempo real, por lo que pueden pasar tan rápido como sea posible.
Sin embargo, si no usas los métodos que sincronizan tus pruebas, no se producirá una recomposición, y la IU se pausará.
@Test
fun counterTest() {
val myCounter = mutableStateOf(0) // State that can cause recompositions.
var lastSeenValue = 0 // Used to track recompositions.
composeTestRule.setContent {
Text(myCounter.value.toString())
lastSeenValue = myCounter.value
}
myCounter.value = 1 // The state changes, but there is no recomposition.
// Fails because nothing triggered a recomposition.
assertTrue(lastSeenValue == 1)
// Passes because the assertion triggers recomposition.
composeTestRule.onNodeWithText("1").assertExists()
}Ten en cuenta que este requisito solo se aplica a las jerarquías de Compose y no al resto de la app.
Cómo inhabilitar la sincronización automática
Cuando llamas a una aserción o una acción a través de ComposeTestRule, como assertExists(), tu prueba se sincroniza con la IU de Compose. En algunos casos, puedes detener esta sincronización y controlar tú mismo el reloj. Por ejemplo, puedes controlar el tiempo para tomar capturas de pantalla precisas de una animación en un punto en el que la IU esté ocupada. Para inhabilitar la sincronización automática, configura la propiedad autoAdvance de mainClock como false:
composeTestRule.mainClock.autoAdvance = false
Normalmente, avanzarás el tiempo tú mismo. Puedes avanzar de a un fotograma con advanceTimeByFrame() o por una duración específica con advanceTimeBy():
composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.mainClock.advanceTimeBy(milliseconds)
Recursos inactivos
Compose puede sincronizar pruebas y la IU para que todas las acciones y aserciones se realicen en estado inactivo, a la espera del reloj o avanzándolo según sea necesario. Sin embargo, algunas operaciones asíncronas cuyos resultados afectan el estado de la IU se pueden ejecutar en segundo plano mientras la prueba no las tiene en cuenta.
Crea y registra estos recursos inactivos en tu prueba para que se los tenga en cuenta cuando determines si la app en cuestión está ocupada o inactiva. No tienes que realizar ninguna acción, a menos que necesites registrar recursos inactivos adicionales, por ejemplo, si ejecutas un trabajo en segundo plano que no se sincroniza con Espresso ni Compose.
Esta API es muy similar a los recursos inactivos de Espresso para indicar si
el sujeto en cuestión está inactivo o ocupado. Usa la regla de prueba de Compose para registrar
la implementación de IdlingResource.
composeTestRule.registerIdlingResource(idlingResource)
composeTestRule.unregisterIdlingResource(idlingResource)
Sincronización manual
En algunos casos, debes sincronizar la IU de Compose con otras partes de la prueba o la app que estás probando.
La función waitForIdle() espera a que Compose esté inactivo, pero la función
depende de la propiedad autoAdvance:
composeTestRule.mainClock.autoAdvance = true // Default
composeTestRule.waitForIdle() // Advances the clock until Compose is idle.
composeTestRule.mainClock.autoAdvance = false
composeTestRule.waitForIdle() // Only waits for idling resources to become idle.
Ten en cuenta que, en ambos casos, waitForIdle() también espera las pasadas de diseño y dibujo
pendientes.
Además, puedes adelantar el reloj hasta que se cumpla una condición determinada con
advanceTimeUntil().
composeTestRule.mainClock.advanceTimeUntil(timeoutMs) { condition }
Ten en cuenta que la condición determinada debe comprobar el estado que puede verse afectado por este reloj (solo funciona con el estado de Compose).
Espera las condiciones
Cualquier condición que dependa de un trabajo externo, como la carga de datos o la medición o el dibujo de Android (es decir, medición o dibujo externo a Compose), debe usar un concepto más general, como waitUntil():
composeTestRule.waitUntil(timeoutMs) { condition }
También puedes usar cualquiera de los
waitUntil asistentes:
composeTestRule.waitUntilAtLeastOneExists(matcher, timeoutMs)
composeTestRule.waitUntilDoesNotExist(matcher, timeoutMs)
composeTestRule.waitUntilExactlyOneExists(matcher, timeoutMs)
composeTestRule.waitUntilNodeCount(matcher, count, timeoutMs)
Recursos adicionales
- Cómo probar apps en Android: La página de destino principal de las pruebas de Android proporciona una visión más amplia de los fundamentos y las técnicas de prueba.
- Aspectos básicos de las pruebas: Obtén más información sobre los conceptos básicos detrás de las pruebas de una app para Android.
- Pruebas locales: Puedes ejecutar algunas pruebas de forma local en tu propia estación de trabajo.
- **Pruebas instrumentadas**: También es recomendable ejecutar pruebas instrumentadas. Es decir, pruebas que se ejecutan directamente integrado en el dispositivo.
- Integración continua: La integración continua te permite integrar tus pruebas en tu canalización de implementación.
- Cómo probar diferentes tamaños de pantalla: Con tantos dispositivos disponibles para los usuarios, debes probar diferentes tamaños de pantalla.
- Espresso: Si bien está diseñada para IUs basadas en View, el conocimiento de Espresso puede ser útil para algunos aspectos de las pruebas de Compose.