Espresso prétend que ce n'est pas nécessaire Thread.sleep();
, mais mon code ne fonctionne que si je l'inclus. Je me connecte à une adresse IP. Lors de la connexion, une boîte de dialogue de progression s'affiche. J'ai besoin sleep
d'attendre que la boîte de dialogue se ferme. Voici mon extrait de test où je l'utilise:
IP.enterIP(); // fills out an IP dialog (this is done with espresso)
//progress dialog is now shown
Thread.sleep(1500);
onView(withId(R.id.button).perform(click());
J'ai essayé ce code avec et sans le Thread.sleep();
mais il dit R.id.Button
n'existe pas. Le seul moyen de le faire fonctionner est de dormir.
En outre, j'ai essayé de remplacer Thread.sleep();
par des choses comme getInstrumentation().waitForIdleSync();
et toujours pas de chance.
Est-ce la seule façon de faire cela? Ou est-ce que je manque quelque chose?
Merci d'avance.
android
testing
android-espresso
Chad Bingham
la source
la source
Réponses:
Dans mon esprit, l'approche correcte sera:
Et puis le modèle d'utilisation sera:
la source
Merci à AlexK pour sa réponse géniale. Dans certains cas, vous devez retarder le code. Il n'attend pas nécessairement la réponse du serveur, mais attend peut-être que l'animation soit terminée. J'ai personnellement un problème avec Espresso idolingResources (je pense que nous écrivons de nombreuses lignes de code pour une chose simple) alors j'ai changé la façon dont AlexK faisait le code suivant:
Vous pouvez donc créer une
Delay
classe et y mettre cette méthode afin d'y accéder facilement. Vous pouvez l'utiliser dans votre classe Test de la même manière:onView(isRoot()).perform(waitFor(5000));
la source
Thread.sleep()
Je suis tombé sur ce fil lorsque je cherchais une réponse à un problème similaire où j'attendais une réponse du serveur et changeait la visibilité des éléments en fonction de la réponse.
Alors que la solution ci-dessus a vraiment aidé, j'ai finalement trouvé cet excellent exemple de chiuki et j'utilise maintenant cette approche comme mon choix chaque fois que j'attends que des actions se produisent pendant les périodes d'inactivité de l'application.
J'ai ajouté ElapsedTimeIdlingResource () à ma propre classe d'utilitaires, je peux maintenant l'utiliser efficacement comme une alternative appropriée à Espresso, et maintenant l'utilisation est agréable et propre:
la source
I/TestRunner: java.lang.NoClassDefFoundError: fr.x.app.y.testtools.ElapsedTimeIdlingResource
erreur. Une idée. J'utilise Proguard mais avec désactiver l'obfuscation.-keep
instruction pour les classes qui ne sont pas trouvées pour vous assurer que ProGuard ne les supprime pas comme inutiles. Plus d'informations ici: developer.android.com/tools/help/proguard.html#keep-codeJe pense que c'est plus facile d'ajouter cette ligne:
Attend un nombre donné de millisecondes (de uptimeMillis) avant de revenir. Similaire à sleep (long), mais ne lance pas InterruptedException; Les événements interrupt () sont différés jusqu'à la prochaine opération interruptible. Ne retourne pas avant que le nombre de millisecondes spécifié ne se soit écoulé.
la source
Vous pouvez simplement utiliser les méthodes Barista:
BaristaSleepActions.sleep(2000);
BaristaSleepActions.sleep(2, SECONDS);
Barista est une bibliothèque qui enveloppe Espresso pour éviter d'ajouter tout le code nécessaire à la réponse acceptée. Et voici un lien! https://github.com/SchibstedSpain/Barista
la source
Thread.sleep()
. Désolé! C'était dans certaines des premières vidéos que Google a faites sur Espresso mais je ne me souviens pas laquelle ... c'était il y a quelques années. Désolé! : ·) Oh! Éditer! J'ai mis le lien vers la vidéo dans le PR que j'ai ouvert il y a trois ans. Vérifiez-le! github.com/AdevintaSpain/Barista/pull/19Ceci est similaire à cette réponse mais utilise un délai d'expiration au lieu de tentatives et peut être enchaîné avec d'autres ViewInteractions:
Usage:
la source
Je suis nouveau dans le codage et l'espresso, alors même si je connais la bonne et raisonnable solution est d'utiliser la marche au ralenti, je ne suis pas encore assez intelligent pour le faire.
Jusqu'à ce que je devienne plus compétent, j'ai encore besoin que mes tests s'exécutent d'une manière ou d'une autre, donc pour l'instant j'utilise cette solution sale qui fait un certain nombre de tentatives pour trouver un élément, s'arrête s'il le trouve et sinon, dort brièvement et démarre jusqu'à ce qu'il atteigne le nombre maximum de tentatives (le nombre le plus élevé de tentatives jusqu'à présent a été d'environ 150).
J'utilise ceci dans toutes les méthodes qui recherchent des éléments par ID, texte, parent, etc.:
la source
findById(int itemId)
méthode retournera un élément (qui pourrait être NULL) si lewaitForElementUntilDisplayed(element);
retourne vrai ou faux .... donc, ce n'est pas okIdlingResource
Cela ne me suffit pas en raison de la granularité du taux d'interrogation de 5 secondes (beaucoup trop gros pour mon cas d'utilisation). La réponse acceptée ne fonctionne pas non plus pour moi (l'explication de pourquoi est déjà incluse dans le long fil de commentaires de cette réponse). Merci pour cela! J'ai pris votre idée et ai fait ma propre solution et cela fonctionne comme un charme.Espresso est conçu pour éviter les appels sleep () dans les tests. Votre test ne doit pas ouvrir une boîte de dialogue pour entrer une adresse IP, qui devrait être la responsabilité de l'activité testée.
D'autre part, votre test d'interface utilisateur doit:
Le test devrait ressembler à ceci:
Espresso attend que tout ce qui se passe à la fois dans le thread d'interface utilisateur et dans le pool AsyncTask se termine avant d'exécuter vos tests.
N'oubliez pas que vos tests ne doivent rien faire qui relève de la responsabilité de votre application. Il doit se comporter comme un "utilisateur bien informé": un utilisateur qui clique, vérifie que quelque chose est affiché à l'écran, mais, en fait, connaît les identifiants des composants
la source
Vous devriez utiliser Espresso Idling Resource, c'est suggéré dans ce CodeLab
Exemple d'un appel asynchrone du présentateur
Dépendances
Pour androidx
Repo officiel: https://github.com/googlecodelabs/android-testing
Exemple IdlingResource: https://github.com/googlesamples/android-testing/tree/master/ui/espresso/IdlingResourceSample
la source
Bien que je pense qu'il soit préférable d'utiliser Idling Resources pour cela ( https://google.github.io/android-testing-support-library/docs/espresso/idling-resource/ ), vous pouvez probablement l'utiliser comme solution de secours:
puis appelez-le dans votre code comme par exemple:
au lieu de
Cela vous permet également d'ajouter des délais d'attente pour les actions d'affichage et les assertions d'affichage.
la source
return new TimedViewInteraction(Espresso.onView(viewMatcher));
avecreturn new TimedViewInteraction(Espresso.onView(viewMatcher).check(matches(isDisplayed())));
Mon utilitaire répète l'exécution exécutable ou appelable jusqu'à ce qu'il réussisse sans erreur ou lance une exécution après un délai. Cela fonctionne parfaitement pour les tests Espresso!
Supposons que la dernière interaction de vue (clic sur le bouton) active certains threads d'arrière-plan (réseau, base de données, etc.). En conséquence, un nouvel écran devrait apparaître et nous voulons le vérifier à notre prochaine étape, mais nous ne savons pas quand le nouvel écran sera prêt à être testé.
L'approche recommandée consiste à forcer votre application à envoyer des messages sur les états des threads à votre test. Parfois, nous pouvons utiliser des mécanismes intégrés comme OkHttp3IdlingResource. Dans d'autres cas, vous devez insérer des morceaux de code à différents endroits des sources de votre application (vous devez connaître la logique de l'application!) Pour tester la prise en charge uniquement. De plus, nous devrions désactiver toutes vos animations (bien que ce soit la partie de l'interface utilisateur).
L'autre approche attend, par exemple SystemClock.sleep (10000). Mais nous ne savons pas combien de temps attendre et même de longs retards ne peuvent garantir le succès. En revanche, votre test durera longtemps.
Mon approche consiste à ajouter une condition de temps pour visualiser l'interaction. Par exemple, nous testons que le nouvel écran doit apparaître pendant 10000 mc (timeout). Mais nous n'attendons pas et le vérifions aussi vite que nous le souhaitons (par exemple toutes les 100 ms) Bien sûr, nous bloquons le fil de test de cette manière, mais généralement, c'est exactement ce dont nous avons besoin dans de tels cas.
Voici ma source de classe:
https://gist.github.com/alexshr/ca90212e49e74eb201fbc976255b47e0
la source
Ceci est une aide que j'utilise dans Kotlin pour les tests Android. Dans mon cas, j'utilise longOperation pour imiter la réponse du serveur, mais vous pouvez l'adapter à votre objectif.
la source
J'ajouterai ma façon de faire cela au mix:
Appelé comme ceci:
Vous pouvez ajouter des paramètres tels que les itérations maximales, la longueur d'itération, etc. à la fonction suspendUntilSuccess.
Je préfère toujours utiliser des ressources inactives, mais lorsque les tests fonctionnent en raison d'animations lentes sur l'appareil par exemple, j'utilise cette fonction et cela fonctionne bien. Il peut bien sûr se bloquer jusqu'à 5 secondes comme avant d'échouer, il pourrait donc augmenter le temps d'exécution de vos tests si l'action pour réussir ne réussit jamais.
la source