Sincroniza tus pruebas

Las pruebas de Compose se sincronizan de forma predeterminada con tu IU. Cuando llamas a un o una acción con ComposeTestRule, la prueba se sincroniza de antemano, 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 a las el resto de la app.

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 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 el dibujo y el diseño pendientes. pases.

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).

Esperar 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 ayudantes waitUntil:

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 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: Más información sobre los conceptos básicos de prueba de una app para Android.
  • Pruebas locales: Puedes ejecutar algunas pruebas de forma 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 las pruebas en tu implementación. en una canalización de integración continua.
  • Prueba diferentes tamaños de pantalla: algunos dispositivos disponibles para los usuarios, debes probar diferentes pantallas tamaños.
  • Espresso: Aunque está diseñado para objetos View basados en IUs y el conocimiento de Espresso puede ser útil para algunos aspectos de Compose. y pruebas.