Synchroniser vos tests

Les tests Compose sont synchronisés par défaut avec votre interface utilisateur. Lorsque vous appelez un ou une action avec le ComposeTestRule, le test est synchronisé à l'avance, en attendant que l'arborescence de l'interface utilisateur soit inactive.

En général, aucune action n'est requise de votre part. Cependant, il existe des situations à connaître.

Lorsqu'un test est synchronisé, votre application Compose est avancée dans le temps à l'aide d'une horloge virtuelle. Les tests Compose ne s'exécutent donc pas en temps réel et peuvent être aussi rapides que possible.

Toutefois, si vous n'utilisez pas les méthodes de synchronisation, aucune recomposition n'est effectuée et l'interface utilisateur semble être interrompue.

@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()
}

Notez que cette exigence ne s'applique qu'aux hiérarchies Compose, et non aux reste de l'application.

Désactiver la synchronisation automatique

Lorsque vous appelez une assertion ou une action via ComposeTestRule, par exemple assertExists(), votre test est synchronisé avec l'interface utilisateur de Compose. Dans certains cas, vous pouvez arrêter cette synchronisation et contrôler vous-même l'horloge. Par exemple, vous pouvez contrôler le moment auquel effectuer des captures d'écran précises d'une animation quand l'interface utilisateur est occupée. Pour désactiver la synchronisation automatique, définissez la propriété autoAdvance de la mainClock sur false :

composeTestRule.mainClock.autoAdvance = false

En général, vous avancerez vous-même le temps. Vous pouvez faire défiler exactement une image avec advanceTimeByFrame() ou une durée spécifique avec advanceTimeBy() :

composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.mainClock.advanceTimeBy(milliseconds)

Ressources inactives

Compose peut synchroniser les tests et l'interface utilisateur afin que chaque action et assertion soit effectuée dans un état inactif, en attendant ou en avançant l'horloge selon le besoin. Cependant, certaines opérations asynchrones dont les résultats affectent l'état de l'interface utilisateur peuvent être exécutées en arrière-plan sans que le test ne les prenne en compte.

Créez et enregistrez ces ressources inactives dans votre test afin qu'elles soient prises afin de déterminer si l'application testée est occupée ou inactive. Vous ne devez pas prendre des mesures, sauf si vous avez besoin d'enregistrer des ressources d'inactivité supplémentaires, par (par exemple, si vous exécutez un job en arrière-plan qui n'est pas synchronisé avec Espresso) Nouveau message.

Cette API est très semblable aux ressources inactives d'Espresso pour indiquer si l'objet testé est inactif ou occupé. Utilisez la règle de test Compose pour enregistrer l'implémentation de IdlingResource.

composeTestRule.registerIdlingResource(idlingResource)
composeTestRule.unregisterIdlingResource(idlingResource)

Synchronisation manuelle

Dans certains cas, vous devez synchroniser l'interface utilisateur de Compose avec d'autres parties de votre test ou avec l'application que vous testez.

La fonction waitForIdle() attend que Compose soit inactif, mais la fonction dépend de la propriété 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.

Notez que dans les deux cas, waitForIdle() attend également que le dessin et la mise en page soient en attente. pass.

Vous pouvez aussi avancer le temps jusqu'à ce qu'advanceTimeUntil() remplisse une certaine condition.

composeTestRule.mainClock.advanceTimeUntil(timeoutMs) { condition }

Notez que la condition précisée doit vérifier l'état pouvant être affecté par cette horloge (elle ne fonctionne qu'avec l'état Compose).

Attendre les conditions

Toute condition qui dépend d'un travail externe, comme le chargement de données ou mesure ou dessin (c'est-à-dire, mesurer ou dessiner en dehors de Compose), doit utiliser un concept plus général tel que waitUntil():

composeTestRule.waitUntil(timeoutMs) { condition }

Vous pouvez également utiliser l'un des Assistants waitUntil:

composeTestRule.waitUntilAtLeastOneExists(matcher, timeoutMs)

composeTestRule.waitUntilDoesNotExist(matcher, timeoutMs)

composeTestRule.waitUntilExactlyOneExists(matcher, timeoutMs)

composeTestRule.waitUntilNodeCount(matcher, count, timeoutMs)

Autres ressources

  • Tester des applications sur Android: les principaux tests Android page de destination offre une vue d'ensemble des principes de base et des techniques de test.
  • Principes de base des tests:en savoir plus sur les concepts fondamentaux des tests d'une application Android.
  • Tests en local:vous pouvez exécuter des tests. localement, sur votre propre poste de travail.
  • Tests d'instrumentation:bon entraînez-vous à exécuter également des tests d'instrumentation. Autrement dit, les tests qui s'exécutent directement sur l'appareil.
  • Intégration continue: L'intégration continue vous permet d'intégrer vos tests dans votre déploiement pipeline.
  • Testez différentes tailles d'écran:avec de nombreux appareils mis à la disposition des utilisateurs, vous devez les tester pour différents écrans différentes tailles d'écran.
  • Espresso: bien qu'il soit destiné aux modèles basés sur les vues IU, la connaissance d'Espresso peut être utile pour certains aspects de Compose. tests.