Dans l' article précédent, nous avons rencontré AirTest IDE , mais juste au cas où, répétons: AirTest IDE a été développé par NetEase et est conçu pour les applications "difficiles à automatiser", telles que les jeux. En fait, ils sont le principal objectif des développeurs, bien que cela ne cesse pas d'utiliser AirTest pour d'autres applications.
Ce travail est le deuxième d'une série consacrée à l'IDE AirTest. Vous pouvez trouver le premier article de synthèse sur AirTest IDE ici , et le troisième et dernier, qui est consacré au cadre d'automatisation Poco UI, par ce lien .
Aujourd'hui, je vais vous parler de l'un des 2 principaux cadres - AirTest. AirTest est un cadre multiplateforme pour automatiser l'interface utilisateur, basé sur les principes de la reconnaissance d'image ( Image Recognition ), qui, selon les développeurs, convient aux jeux et aux applications. Le projet AirTest sur GitHub contient 4 projets: Airtest , Poco , iOS-Tangent , multi-device-runner .
Et maintenant passons à la partie amusante!

Fonctionnement d'AirTest
AirTest traite les captures d'écran résultantes en fonction du processus de seuillage . L'essentiel est de comparer l'intensité des pixels de l'image avec un certain nombre ( valeur seuil ) et, si la valeur du pixel est supérieure, de lui attribuer une couleur (le blanc est le plus souvent utilisé). Sinon, une couleur différente est attribuée - le noir. Par conséquent, la sortie est une image en noir et blanc. Une limitation naturelle en découle - AirTest ne prend pas en compte la couleur lors de la reconnaissance. Par exemple, si vous utilisez un objet avec la même silhouette, mais différent, par exemple, la coloration et que vous devez vérifier la présence d'un élément avec une palette de couleurs spécifique, cela sera extrêmement difficile et peut ne pas fonctionner du tout.
Par exemple, dans le cadre du test IDE AirTest, il a été décidé de travailler avec le jeu Marvel Puzzle Quest . Lors du chargement, les personnages de cet univers de bande dessinée clignotent à l'écran dans un certain ordre. De temps en temps, leurs costumes changent et c'est la première fois que je suis alerté. Dans l'exemple ci-dessous, je m'attendais, dans le cadre du test, à Spider-Man dans le classique, et reçu dans un costume furtif. En fait, le test a réussi, mais cela s'est produit à cause de ce qui précède - l'utilisation d'une image en noir et blanc pendant la reconnaissance. Un exemple de ce qui était attendu et de ce qui s'est finalement produit:

Amélioration des chances de réussite des tests
Comme vous l'avez déjà compris, la reconnaissance d'image est loin d'être une panacée, bien qu'elle fonctionne bien ici. Pour écrire des tests de qualité, vous ne pouvez pas éviter d'écrire du code et, par conséquent, de connaître les bases de Python. Par exemple, avant de rechercher un élément spécifique, il serait bon de s'assurer qu'il est bien à l'écran. Il y a des moments où AirTest «manque» et peut prendre le mauvais article pour celui dont vous avez besoin. De temps en temps, il y a des problèmes avec la reconnaissance du texte que vous voulez trouver en utilisant la reconnaissance d'image. AirTest peut confondre les résultats et supposer que le texte dont vous avez besoin est à l'écran, mais, en fait, le texte est complètement différent. Le processus d'analyse des résultats est conçu pour simplifier le système de rapport qui est déjà intégré dans l'IDE AirTest. Vous pouvez créer et ouvrir un rapport une fois le test / script terminé à l'aide du raccourci clavier Ctrl / Cmd + L.
Selon les recommandations générales, je voudrais également souligner les points suivants.
- Prenez des captures d'écran des éléments dont vous avez besoin. Je veux dire, si vous avez besoin d'un bouton qui, par exemple, est sur une texture complexe à l'arrière, essayez de faire un écran uniquement avec le bouton afin de ne pas perdre de temps à traiter l'arrière, ce qui, en fait, n'est pas nécessaire. Dans ce cas, la recherche ne dépendra pas de ce qui est affiché sur le fond et vous obtiendrez un résultat plus précis en moins de temps.
- Essayez d'éviter la reconnaissance d'images qui ne contiennent que du texte, comme la reconnaissance réussie ("taux de réussite") dans ce cas sera considérablement réduite.
- Bien que la création de captures d'écran pendant l'enregistrement automatique de code (enregistrement automatique de script) soit une fonction assez pratique, mais à certains endroits, les captures d'écran ne sont pas très informatives. Il est préférable de les créer manuellement afin de stocker des informations de recherche plus utiles dans vos photos.
Et si vous voulez demander "Est-il possible de modifier les paramètres du processus de recherche d'images?", Alors je vais vous répondre - oui, c'est possible.
Paramètres de reconnaissance d'image
L'utilisateur est autorisé et encouragé à travailler avec les paramètres de reconnaissance d'image pour obtenir les résultats souhaités, pour optimiser le temps et la probabilité de reconnaissance réussie des éléments (taux de réussite) à l'écran. Ces paramètres sont stockés dans la fenêtre de l'éditeur d'image et pour l'ouvrir, vous devez double-cliquer sur l'image souhaitée dans l'éditeur de script. Les paramètres de reconnaissance de chaque image doivent être modifiés séparément ou des variables globales doivent être utilisées si, par exemple, vous souhaitez augmenter les exigences de précision pour l'opération de seuil pour votre projet.
Fenêtre de l'éditeur d'images L'Editeur d'images contient une zone de travail, ainsi que des boutons "Instantané + Reconnaissance" et "Afficher l'aide". Le premier est chargé de comparer votre image actuelle avec la version de l'instantané. L'image instantanée est capturée à partir de la fenêtre actuelle sur votre appareil. Le deuxième bouton ouvre le manuel fonctionnel de l'éditeur d'images. Dans la partie droite de la fenêtre, l'image de recherche actuelle est affichée, ainsi que des paramètres tels que le nom de fichier, le seuil, target_pos et rgb.
- Le champ du nom de fichier est responsable du nom de l'image actuellement enregistrée (toutes les images sont enregistrées dans le dossier du projet).
- seuil enregistre la valeur du pourcentage de coïncidence (de 0 à 1) des images après reconnaissance. Plus la valeur est élevée, plus l'exigence de précision de correspondance d'image est élevée. Comme mentionné ci-dessus, AirTest convertit les images en noir et blanc (en fonction de la mise en œuvre du seuil) et, par conséquent, la couleur n'est pas prise en compte lors de la reconnaissance.
- La case à cocher RVB est conçue pour «activer et ajouter» de la couleur lors de la reconnaissance d'image et ainsi commencer à en tenir compte. Cependant, gardez à l'esprit que l'inclusion de cette fonctionnalité ne garantit toujours pas 100% du résultat. Par exemple, si vous avez 2 boutons identiques qui ne diffèrent que par la couleur d'arrière-plan, la probabilité d'une reconnaissance incorrecte (par exemple, dans assert_exists / assert_not_exists) sera assez élevée.
- target_pos est responsable du point de l'image sur lequel AirTest clique après la reconnaissance. Par défaut, la valeur est 5, mais vous pouvez la changer de 1 à 9, où 1 est le coin supérieur gauche de votre image de travail et 9 est le coin inférieur droit. L'emplacement des neuf points est clairement indiqué dans la capture d'écran ci-dessous. Vous pouvez également lire à ce sujet dans la documentation officielle.
Dans cet exemple, le bouton central est sélectionné pour la reconnaissance. Le contour montre les bordures de la sélection.

Écriture de tests automatisés avec AirTest
Toutes les commandes de travail du framework AirTest se trouvent dans la fenêtre AirTestAssistant dans le coin supérieur gauche de l'IDE Airtest. S'il n'y est pas, vous pouvez définir la disposition de fenêtre par défaut à l'aide de Fenêtre -> Disposition par défaut .
Emplacement de la fenêtre de l'assistant AirTest Dans la version actuelle du programme, vous pouvez utiliser les commandes suivantes disponibles dans la fenêtre de l'Assistant AirTest:
- tactile - cette commande simule un geste tactile sur un appareil mobile. Touch a les paramètres suivants - touch (v, times = 1, duration = 0.01, right_click = False).
- v - image ou coordonnée (x, y)
- fois - le nombre de clics. La valeur par défaut est 1
- durée - la durée de la mise en attente après avoir touché l'écran. Avec ce paramètre, vous pouvez simuler un "appui long" (long_touch). La valeur par défaut est 0,01 seconde.
- clic droit - cliquez sur le "bouton droit de la souris". Ne peut être utilisé que dans les programmes Windows.
- wait - en attente de l'élément d'interface utilisateur. La commande a les paramètres suivants - attendre (v, timeout = TIMEOUT, intervalle = 5, intervalfunc = None).
- v - l'image que le programme attend
- timeout - timeout. La valeur par défaut est 20.
- intervalfunc - fonction utilisateur (personnalisée). Si l'image n'est pas trouvée, cette fonction sera exécutée.
- interval - intervalle entre la comparaison d'images
La fonction retourne ce qui suit: si une image est trouvée, alors les coordonnées centrales de l'image donnée sont retournées, sinon TargetNotFoundError est levée
- swipe - cette commande simule un geste de glissement sur un appareil mobile ("glissement de l'écran"). Swipe a les paramètres suivants: swipe (v1, v2 = None, vector = None, duration = 0.01).
- v1 - la valeur à partir de laquelle svayp commence. Il peut s'agir d'une image ou d'une coordonnée donnée (x, y)
- v2: glissez la valeur de fin (la commande est exécutée de v1 à v2). Ce paramètre a une priorité plus élevée que le paramètre "vecteur"
- vecteur [x, y] - est créé pendant le fonctionnement d'AirTest ou vous pouvez le définir vous-même. Indique le chemin à parcourir. Pour balayer vers la droite, X doit être positif, à son tour, Y doit être positif pour balayer vers le bas.
- étapes - n'a pas utilisé ce paramètre et n'a pas trouvé comment il est appliqué dans la pratique. L'info-bulle donne ce qui suit: "le nœud dans le chemin de balayage, 5 par défaut". Je suppose que le vecteur de direction de balayage sera divisé en «sections» et au lieu de permuter instantanément du point A au point B, le balayage sera simulé avec de petites pauses dans les nœuds spécifiés dans ce paramètre, comme s'il simulait un mouvement par phases. Par exemple, si la valeur est 5, le vecteur sera divisé en 5 segments.
- duration - la durée du balayage. La valeur par défaut est 0,5 seconde.
- existe - une vérification existe pour l'élément que vous attendez sur l'écran du moniteur de l'appareil. existe a les paramètres suivants: existe (v)
- v - image
La fonction retourne ce qui suit: si une image est trouvée, alors les coordonnées du centre de l'image sont retournées, sinon False.
- text - commande de saisie de texte . text a les paramètres suivants: text (text, enter = True, search = False)
- texte - chaîne de texte à saisir
- enter - ce paramètre est responsable de l'opportunité d'utiliser "Enter" après avoir saisi du texte. La valeur par défaut est True.
- recherche - n'a pas utilisé ce paramètre et n'a pas trouvé comment il est appliqué dans la pratique. L'info-bulle donne les informations suivantes: "forcer" Rechercher "ou non après la saisie". La valeur par défaut est False.
- keyevent - émulation de la pression de boutons physiques sur l'appareil, tels que HOME, BACK, MENU, POWER, etc. Paramètres de cette commande: keyevent (keyname)
- keyname - nom du bouton (POWER, HOME, etc.)
- instantané - créer une capture d'écran de l'écran dans l'état actuel. Options par défaut: instantané (nom de fichier = Aucun, msg = "test-point")
- nom de fichier - enregistrez la capture d'écran actuelle dans un fichier séparé. Vous pouvez ignorer cette option.
- msg - description de ce point de test. Ce texte sera affiché dans le rapport HTML, qui peut être créé après le test.
Cette fonction renvoie les éléments suivants: nom de fichier (nom de fichier).
- sommeil - le test de course "s'endort" pendant un certain temps. Valeurs par défaut: sleep (secs = 1.0)
- secs - timeout. La valeur par défaut est 1 seconde.
- assert_exists - vérifie si un élément existe. Paramètres de cette commande: assert_exists (v, msg = "test-point")
- v - image avec l'élément dont la présence est vérifiée
- msg - description de ce point de test. Ce texte sera affiché dans le rapport HTML, qui peut être créé après le test.
Cette fonction retourne ce qui suit: si une image est trouvée, alors les coordonnées du point central de cette image sont retournées, sinon une AssertionError est levée
- assert_not_exists - vérifie que l'élément n'est pas présent sur l'écran de l'appareil. Paramètres pour cette commande: assert_not_exists (v, msg = "test-point")
- v - image avec l'élément dont la présence est vérifiée
- msg - description de ce point de test. Ce texte sera affiché dans le rapport HTML, qui peut être créé après le test.
- assert_equal - vérifie que l'attribut est égal à la valeur spécifiée. Paramètres pour cette commande: assert_equal (premier, deuxième, msg = "test-point")
- premier - le premier élément à comparer
- second - le deuxième élément à comparer
- msg - description de ce point de test. Ce texte sera affiché dans le rapport HTML, qui peut être créé après le test.
- assert_not_equal - vérifie que l'attribut n'est pas égal à la valeur spécifiée. Paramètres pour cette commande: assert_not_equal (first, second, msg = "test-point")
- premier - le premier élément à comparer
- second - le deuxième élément à comparer
- msg - description de ce point de test. Ce texte sera affiché dans le rapport HTML, qui peut être créé après le test.
Ces commandes sont divisées en 3 groupes principaux: opérations, fonctions auxiliaires et assertions . Vous pouvez sélectionner le groupe dont vous avez besoin en utilisant le filtre approprié (un menu déroulant juste en dessous du nom de la fenêtre).
Filtre de groupe d'équipe Les équipes qui ont besoin d'une image activent les fonctions d'enregistrement de capture d'écran immédiatement après avoir cliqué sur le bouton correspondant. Par exemple, pour sélectionner l'élément à cliquer sur l'écran, sélectionnez la commande tactile dans AirTest Assistant et dans la fenêtre Écran de l'appareil, sur l'appareil actif, encerclez l'élément sur lequel vous souhaitez cliquer. Après cela, la commande correspondante apparaîtra dans la fenêtre principale (Script Editor), dans notre cas, touchez, avec l'image comme paramètre. En conséquence, le processus d'automatisation est le suivant (le gif a été enregistré à partir d'une version obsolète d'AirTest IDE):

Si, pour une raison quelconque, vous ne souhaitez pas créer manuellement des captures d'écran et / ou écrire du code en général, vous pouvez utiliser la fonction d'enregistrement automatique. Vous pouvez l'activer en cliquant sur le bouton "caméra" en face du menu déroulant avec des groupes de commandes dans la fenêtre de l'Assistant Airtest. L'enregistrement automatique est une chose assez précise et pratique, mais, bien sûr, ce n'est pas une panacée et ne remplacera pas la composition manuelle de code.

Il convient de mentionner 3 touches de raccourci supplémentaires - F5 (démarrer le script), F10 (arrêter le script en cours), Ctrl + L / Cmd + L (créer un rapport basé sur le test terminé).
Vous pouvez exécuter des tests prêts à l'emploi sans interface utilisateur à l'aide du terminal (ligne de commande). Vous trouverez plus d'informations à ce sujet en général et sur l'exécution de tests en particulier ici .
Un exemple d'un extrait d'un test écrit en utilisant le framework AirTest peut être trouvé sous le spoiler!
Exemple d'autotest écrit à l'aide d'AirTest (reconnaissance d'image) L'interface utilisateur de votre application / jeu ne se compose pas entièrement d'icônes, de boutons, de dos, etc. uniques. De plus, des éléments périodiquement visuellement identiques peuvent être trouvés sur un seul écran, par exemple des boutons, des curseurs, etc. Le plus souvent, dans de tels cas, AirTest ne pourra pas reconnaître l'élément dont vous avez besoin et soit le test échouera avec erreur, soit le mauvais élément d'interface sera sélectionné pour d'autres manipulations.
Un exemple de fenêtre avec plusieurs éléments identiques Surtout pour de tels cas, un autre cadre a été développé qui est déjà intégré à l'IDE AirTest. Il est Poco et a été brièvement décrit dans un article avec un aperçu de l'IDE Airtest . Je vais vous en dire plus sur ce framework dans le prochain article.
Dites-nous si vous avez déjà utilisé l'IDE AirTest et ce que vous pensez de cet outil. Je serai heureux de discuter dans les commentaires!