Guides pratiques

Alternatives aux ressources inactives dans les tests Compose : les API waitUntil (mise à jour)

Temps de lecture : 3 min
Jose Alcérreca
Ingénieur en relations avec les développeurs

Dans cet article, vous découvrirez comment utiliser l'API de test waitUntil dans Compose pour attendre que certaines conditions soient remplies. Il s'agit d'une bonne alternative à l'utilisation des ressources inactives dans certaines situations.

[Mise à jour 2023] En bref : utilisez les nouvelles API waitUntil pour effectuer une synchronisation dans les tests Compose (v1.4.0 et versions ultérieures).


Qu'est-ce que la synchronisation ?

Il existe plusieurs façons de classer les tests, par exemple en fonction de leur portée. Les petits tests, ou tests unitaires, se concentrent sur de petits éléments de votre application, tandis que les grands tests, ou tests de bout en bout, couvrent une grande partie de votre application. Pour en savoir plus sur ces types de tests et d'autres, consultez la documentation sur les tests récemment mise à jour.

Appuyez sur Entrée ou cliquez pour afficher l'image en taille réelle

large_0_9n_Nqkt_HHUTOQ_In_AI_b113b43bcf.png
Différentes portées de test dans une application

La synchronisation est le mécanisme qui permet au test de savoir quand exécuter l'opération suivante. Plus le bloc de code que vous choisissez de vérifier est important, plus il est difficile de le synchroniser avec le test. Dans les tests unitaires, il est facile de contrôler entièrement l'exécution du code à vérifier. Toutefois, à mesure que nous élargissons la portée pour inclure davantage de classes, de modules et de couches, il devient difficile pour le framework de test de savoir si l'application est en cours d'opération ou non.

Appuyez sur Entrée ou cliquez pour afficher l'image en taille réelle

large_correct_b1a355f41b.webp
Synchronisation correcte entre le test et l'application

androidx.test et, par extension, Compose Test, utilisent quelques astuces en arrière-plan pour que vous n'ayez pas à vous en soucier. Par exemple, si le thread principal est occupé, le test s'interrompt jusqu'à ce qu'il puisse exécuter la ligne suivante.

Toutefois, ils ne peuvent pas tout savoir. Par exemple, si vous chargez des données dans un thread en arrière-plan, le framework de test peut exécuter l'opération suivante trop tôt, ce qui fait échouer votre test. Le pire, c'est lorsque cela ne se produit que dans un faible pourcentage de cas, ce qui rend le test instable.

Option 1 : Ressources inactives

Les ressources inactives sont une fonctionnalité Espresso qui vous permet, en tant que développeur, de décider quand l'application est occupée. Vous pouvez les utiliser de deux manières :

1. En les installant dans le framework ou la bibliothèque qui effectue un travail que le test ne peut pas voir.

RxIdler, qui encapsule un planificateur RxJava, en est un bon exemple. Il s'agit de la méthode recommandée pour enregistrer les ressources inactives, car elle vous permet de séparer clairement la configuration de votre test du code de test.

2. En modifiant votre code en cours de test pour exposer explicitement des informations indiquant si votre application est occupée ou non.

Par exemple, vous pouvez modifier votre dépôt (ou un test double) pour indiquer qu'il est occupé lors du chargement des données à partir d'une source de données :

Cette solution n'est pas idéale, car vous polluez votre code de production ou créez des tests doubles compliqués, et il est parfois difficile de les installer. Par exemple, comment utiliser les ressources inactives dans un flux Kotlin ? Quelle mise à jour est la dernière ?

Au lieu de cela, nous pouvons attendre que les choses se produisent.

Option 2 : Attendre que les choses se produisent… de la mauvaise manière

Le chargement des données est généralement rapide, en particulier lorsque vous utilisez des données factices. Alors, pourquoi perdre du temps avec des ressources inactives alors que vous pouvez simplement mettre le test en veille pendant quelques secondes ?

Ce test s'exécutera plus lentement que nécessaire ou échouera. Lorsque vous avez des centaines ou des milliers de tests d'interface utilisateur, vous voulez qu'ils soient aussi rapides que possible.

De plus, les émulateurs ou les appareils se comportent parfois mal et saccadent, ce qui fait que l'opération prend un peu plus de temps que ces 2 000 ms, ce qui interrompt votre build. Lorsque vous avez des centaines de tests, cela devient un problème majeur.

0_DOCdjq-JpPDGV5OB.png

Option 3 : Attendre que les choses se produisent de la bonne manière

Si vous ne souhaitez pas modifier votre code en cours de test pour exposer quand il est occupé, vous pouvez également attendre qu'une certaine condition soit remplie au lieu d'attendre une durée arbitraire.

1_jIYFxE4qlHXMi2SwW6JemA.png

Dans Compose, vous pouvez exploiter la fonction waitUntil, qui utilise une autre fonction qui produit un booléen.

Mise à jour du 22/03/2023 : à partir de Compose 1.4.0, nous avons ajouté un nouvel ensemble d'API waitUntil :

[Avant la version 1.4.0 : utilisez ces assistants : waitUntilExists, waitUntilNodeCount]

…et utilisez-les comme suit :

N'utilisez ces API que lorsque vous devez synchroniser votre test avec l'interface utilisateur. La synchronisation sur chaque instruction de test pollue inutilement le code de test, ce qui le rend plus difficile à maintenir.

Quand devez-vous l'utiliser ? Un bon cas d'utilisation consiste à charger des données à partir d'un observable (avec LiveData, Kotlin Flow ou RxJava). Lorsque votre interface utilisateur doit recevoir plusieurs mises à jour avant d'être considérée comme inactive, vous pouvez simplifier la synchronisation à l'aide de waitUntil.

Par exemple, lorsque vous collectez un flux à partir d'une vue :

Et que vous émettez plusieurs éléments :

Si repository met un temps indéterminé à renvoyer le premier résultat, le framework de test pensera que "Loading" est l'état inactif (la valeur initiale attribuée dans collectAsState) et passera à l'instruction suivante.

Vous pouvez donc rendre le test beaucoup plus fiable en vous assurant que l'interface utilisateur n'affiche pas l'indicateur de chargement :


Bon… attendez… test !


Licence des extraits de code :

Copyright 2022 Google LLC.
SPDX-License-Identifier: Apache-2.0
Écrit par :

Lire la suite