Introduction aux tests iOS avec UI Automation

Imaginez pouvoir écrire des scripts qui interagissent automatiquement avec votre application iOS et être en mesure de vérifier les résultats. Avec UI Automation, vous pouvez. UI Automation est un outil fourni par Apple pour effectuer un niveau plus élevé de tests sur votre application iOS au-delà de tout ce qui est réalisable avec XCTest..

1. Essai de la boîte blanche contre la boîte noire

Vous avez peut-être entendu parler de la comparaison entre le test de la boîte blanche et celle de la boîte noire en ce qui concerne la manière de tester un logiciel. Si vous ne connaissez pas ces concepts, laissez-moi vous expliquer comment ils fonctionnent..

Test de la boîte blanche

Imaginez qu’un logiciel s’exécute dans une boîte. Avec les tests de la boîte blanche, vous pouvez voir à l'intérieur de la boîte et regarder tous les éléments essentiels du fonctionnement du logiciel, puis prendre des décisions éclairées sur la façon de tester le logiciel. Vous pouvez également avoir des crochets de niveau plus profonds dans le logiciel à partir des tests que vous écrivez..

Le test unitaire est le test de la boîte blanche. Lors de l'écriture des tests unitaires, le testeur dispose d'un accès fin au code sous test. Le testeur peut réellement écrire des tests qui exploitent le logiciel testé au niveau de la méthode ou de l’unité..

Dans le développement de logiciels iOS, nous utilisons le XCTest cadre pour effectuer ce type de test. Regardez un autre tutoriel que j'ai écrit sur comment démarrer avec XCTest.

Test de la boîte noire

Dans les tests de boîte noire, la boîte est opaque. Le testeur ne peut pas voir à l'intérieur de la boîte. Le testeur ne peut ni accéder ni connaître la mise en œuvre de la base de code pour écrire des tests. Au lieu de cela, le testeur est obligé d'utiliser l'application comme le ferait un utilisateur final en interagissant avec l'application et en attendant sa réponse, en vérifiant les résultats..

Il y a au moins deux façons d'exécuter ce type de test.

  • Un testeur qui effectue de manière répétée et manuelle un certain nombre d'étapes prédéfinies et vérifie visuellement les résultats.
  • Utilisez des outils spécialisés pour tester l'application avec des API dont le comportement est similaire à celui d'une interaction humaine..

Dans le développement d'applications iOS, Apple fournit un outil appelé UI Automation effectuer des tests de boîte noire.

2. Qu'est-ce que l'automatisation de l'interface utilisateur?? 

UI Automation est un outil fourni et maintenu par Apple pour les tests automatisés de niveau supérieur d'applications iOS. Les tests sont écrits en JavaScript, conformément à une API définie par Apple..

L'écriture de tests peut être facilitée en s'appuyant sur des étiquettes d'accessibilité pour les éléments d'interface utilisateur de votre application. Ne vous inquiétez pas cependant, si vous ne les avez pas définis, il existe des alternatives.

L'API UI Automation ne dispose pas du format typique basé sur xUnit pour l'écriture de tests. Une différence avec les tests unitaires est que le testeur doit enregistrer manuellement les succès et les échecs. Les tests UI Automation sont exécutés à partir de l'instrument Automation dans la Instruments outil fourni avec les outils de développement d’Apple. Les tests peuvent être exécutés dans le simulateur iOS ou sur un périphérique physique..

3. Écrire des tests d'automatisation de l'interface utilisateur

Étape 1: Ouvrez l'exemple de projet

J'ai mis à jour le projet exemple utilisé dans le précédent tutoriel sur les tests iOS avec des éléments d'interface utilisateur supplémentaires fournissant des points d'ancrage utiles pour l'ajout de tests UI Automation. Téléchargez le projet depuis GitHub. Ouvrez le projet et exécutez l'application pour vous assurer que tout fonctionne comme prévu. Vous devriez voir une interface utilisateur semblable à celle présentée ci-dessous.


Avant d'écrire des tests, n'hésitez pas à essayer l'exemple d'application pour vous familiariser avec ses fonctionnalités. En tant qu’utilisateur, vous pouvez saisir du texte dans le champ de texte et appuyer sur le bouton pour afficher une étiquette à l’écran indiquant la chaîne entrée et inversée..

Étape 2: Créer un test UI Automation

Maintenant que vous êtes familiarisé avec l'exemple d'application, il est temps d'ajouter un test UI Automation. UI Automation est un outil que vous pouvez trouver dans Instruments. Pour exécuter l’exemple d’application dans Instruments, sélectionnez Produit> Profil dans le menu de Xcode. Sélectionner Automatisation de la liste des outils.


La fenêtre principale Instruments s'ouvre avec un seul instrument prêt à fonctionner, l'instrument Automation (l'instrument Automation exécute les cas de test UI Automation). Vous verrez également une zone dans la moitié inférieure de la fenêtre qui ressemble à un éditeur de texte. Ceci est l'éditeur de script. C'est ici que vous écrivez vos tests UI Automation. Pour ce premier test, suivez les instructions ci-dessous, en ajoutant chaque ligne au script dans l'éditeur de script..

Commencez par stocker une référence au champ de texte dans une variable.

var inputField = target.frontMostApp (). mainWindow (). textFields () ["Champ de saisie"];

Définir la valeur du champ de texte.

inputField.setValue ("hi");

Vérifiez que la valeur a été définie avec succès et, le cas échéant, passez le test. Échouer le test si ce n'était pas.

if (inputField.value ()! = "hi") UIALogger.logFail ("Le champ de saisie N'A PAS pu être défini avec la chaîne!"); else UIALogger.logPass ("Le champ de saisie a pu être défini avec la chaîne!");

Bien que ce test soit relativement simple, il a une valeur. Nous venons d'écrire un test qui teste la présence d'un champ de texte au lancement de l'application et qui permet de déterminer si une chaîne aléatoire peut être définie comme valeur du champ de texte. Si vous ne me croyez pas, supprimez le champ de texte du storyboard et lancez le test. Vous verrez que cela échoue.

Ce test illustre trois éléments importants de l’écriture de tests UI Automation. Tout d'abord, il vous montre comment accéder à un élément d'interface utilisateur simple, le champ de texte. Plus précisément, nous accédons à un dictionnaire de tous les champs de texte de la vue de base de l’application via target.frontMostApp (). mainWindow (). textFields () et nous trouvons ensuite le champ de texte qui nous intéresse en recherchant celui avec la clé Champ de saisie. Cette clé est en fait le libellé d'accessibilité du champ de texte. Dans ce cas, c'est défini dans le storyboard. Nous pouvons également définir l’étiquette d’accessibilité dans le code à l’aide de la touche accessibilitéLabel propriété sur NSObject.

L'accès à la fenêtre principale de l'application, à l'application la plus en avant et à la cible est courant lorsque vous utilisez UI Automation. Je vais vous montrer comment rendre ceci plus facile et moins bavard plus tard dans ce tutoriel..

Deuxièmement, cela vous montre que vous pouvez interagir avec les éléments de l'interface utilisateur à l'écran. Dans ce cas, nous définissons la valeur du champ de texte, imitant l’utilisateur interagissant avec l’application en entrant du texte dans le champ de texte..

Et troisièmement, l'exemple montre également une technique permettant de vérifier ce qui se passe dans l'application. Si la valeur est définie avec succès, le test réussit. Si la valeur n'est pas définie, le test échoue.

Étape 3: Enregistrement des tests

Bien que l’écriture de tests dans l’éditeur de script soit pratique, elle devient rapidement encombrante et difficile à gérer. Si vous quittez Instruments, toutes les modifications non enregistrées sont ignorées. Nous devons sauvegarder les tests que nous écrivons. Copiez et collez simplement votre test dans un nouveau document dans votre éditeur de texte préféré et sauvegardez-le. Vous pouvez trouver les tests créés dans ce tutoriel dans le projet exemple sous Jumblify / JumblifyTests / AutomationTests.js.

Pour exécuter le test, sélectionnez l’onglet du milieu dans le volet de droite, à côté de l’éditeur de script, puis sélectionnez Ajouter> Importer.


Vous serez invité à sélectionner le script à importer. Accédez au script enregistré et importez-le. Vous pouvez toujours changer le script dans l'éditeur de script. Toutes les modifications seront automatiquement enregistrées dans le fichier externe que vous avez créé..

Étape 4: appuyer sur un bouton

Mettons à jour notre test pour tester l'interaction avec le bouton. Notre test ajoute déjà du texte au champ de texte. Il suffit donc d’ajouter du code pour appuyer sur le bouton. Voyons tout d’abord comment trouver le bouton dans la vue pour pouvoir l’exploiter. Il y a au moins trois façons d'accomplir cela et chaque approche a ses inconvénients..

Approche 1

Nous pouvons appuyer par programme sur une coordonnée (X, Y) à l'écran. Nous faisons cela avec la ligne de code suivante:

target.tap (x: 8,00, y: 50,00);

Bien sûr, je ne sais pas si ce sont même les coordonnées du bouton à l'écran et je ne vais pas m'en inquiéter, car cette approche n'est pas le bon outil pour ce travail. Je ne fais que le mentionner pour que vous sachiez qu'il existe. En utilisant le robinet méthode sur cible appuyer sur un bouton est sujet à des erreurs, car ce bouton peut ne pas toujours être à cette coordonnée spécifique.

Approche 2

Il est également possible de trouver le bouton en recherchant dans le tableau de boutons de la fenêtre principale, de la même manière que nous avons accédé au champ de texte lors du premier test. Au lieu d'accéder au bouton directement à l'aide d'une clé, nous pouvons récupérer un tableau de boutons dans la fenêtre principale et coder en dur un index de tableau pour obtenir une référence au bouton..

target.frontMostApp (). mainWindow (). buttons () [0] .tap ();

Cette approche est un peu meilleure. Nous ne codons pas en dur une coordonnée, mais nous codons en dur un index de tableau pour trouver le bouton. Si nous ajoutons un autre bouton sur la page, cela peut accidentellement rompre ce test.

Approche 3

Cela m'amène à la troisième façon de trouver le bouton sur la page, en utilisant des étiquettes d'accessibilité. En utilisant une étiquette d'accessibilité, nous pouvons accéder directement au bouton comme si nous trouvions un objet dans un dictionnaire à l'aide d'une clé.

target.frontMostApp (). mainWindow (). buttons () ["Bouton Jumblify"]. tap ();

Cependant, si vous ajoutez la ligne ci-dessus au script et l'exécutez, vous obtiendrez une erreur..


En effet, nous n'avons pas encore défini l'étiquette d'accessibilité pour le bouton. Pour ce faire, basculez vers Xcode et ouvrez le story-board du projet. Trouvez le bouton dans la vue et ouvrez le Inspecteur d'identité sur la droite (Affichage> Utilitaires> Inspecteur d'identité). Veiller à ce que Accessibilité est activé et définissez le Étiquette pour le bouton Bouton Jumblify.


Pour relancer le test, vous devez exécuter l'application à partir de Xcode en sélectionnant Produit > Courir puis profilez à nouveau l'application en sélectionnant Produit > Profil. Ceci exécute les tests et chaque test devrait réussir maintenant.

Étape 5: Vérifiez la chaîne de brouillage 

Comme je l'ai mentionné précédemment, notre application utilise une chaîne de texte en entrée et, lorsque l'utilisateur appuie sur le bouton, affiche la chaîne inversée. Nous devons ajouter un test supplémentaire pour vérifier que la chaîne d'entrée est correctement inversée. Pour vérifier que le UILabel est rempli avec la chaîne correcte, nous devons comprendre comment référencer le UILabel et vérifiez la chaîne affichée. Il s’agit d’un problème courant lors de la rédaction de tests d’automatisation, c’est-à-dire de la manière de référencer un élément dans l’application pour lui faire une affirmation.

Il y a une méthode sur presque tous les objets de l'API UI Automation, logElementTree. Cette méthode enregistre les éléments imbriqués d'un élément donné. Ceci est très utile pour comprendre la hiérarchie des éléments dans l'application et aide à comprendre comment cibler un élément spécifique..

Voyons comment cela fonctionne en enregistrant l'arborescence des éléments de la fenêtre principale. Regardez la ligne de code suivante.

target.frontMostApp (). mainWindow (). logElementTree ();

L'ajout de cette ligne au script de test produit le résultat suivant:


Comme vous pouvez le voir, il y a un UIAStaticText sous-élément du UIAWindow et vous pouvez aussi voir qu'il a un nom de ih, qui se trouve être également la chaîne inversée que nous devons vérifier. Maintenant, pour terminer notre test, nous avons juste besoin d'ajouter du code pour accéder à cet élément et vérifier qu'il est présent..

Pourquoi avons-nous seulement besoin de vérifier si le UIAStaticText l'élément est présent?Le nom de l'élément étant la chaîne inversée de la chaîne d'entrée, la vérification de sa présence confirme que la chaîne a été correctement inversée. Si l'élément n'existe pas lorsqu'il est référencé par nom-la chaîne inversée-cela signifie que la chaîne n'a pas été correctement inversée.

var stringResult = target.frontMostApp (). mainWindow (). staticTexts () ["ih"]; if (! stringResult.isValid ()) UIALogger.logFail ("Le texte de sortie n'a PAS été défini avec la chaîne correctement inversée!"); else UIALogger.logPass ("Le texte de sortie a été défini avec la chaîne correctement inversée!");

4. Gratter la surface

Il existe de nombreuses autres façons pour un utilisateur final d'interagir avec un appareil iOS tout en utilisant votre application. Cela signifie qu'il existe de nombreuses autres manières d'utiliser UI Automation pour simuler ces interactions. Plutôt que de tenter de capturer une liste complète de ces interactions, je vous dirigerai vers la documentation de référence UI Automation..

Pour chaque type d'objet avec lequel vous pouvez interagir, vous pouvez afficher la liste des méthodes disponibles sur cet objet. Certaines méthodes permettent de récupérer des attributs concernant l’objet tandis que d’autres servent à simuler une interaction tactile, telles que flickInsideWithOptions sur UIAWindow.

Enregistrement d'une session

En essayant de tester de plus en plus d'applications compliquées avec UI Automation, vous constaterez qu'il est parfois fastidieux d'utiliser de manière répétée logElementTree pour trouver l'élément que vous recherchez. Cela devient également fastidieux et complexe pour les applications avec une hiérarchie de vues complexe ou une navigation. Dans ces cas, vous pouvez utiliser une autre fonctionnalité de Instruments enregistrer un ensemble d'interactions utilisateur. Ce qui est encore plus cool, c’est que Instruments génère le code JavaScript UI Automation qui est nécessaire pour reproduire les interactions enregistrées. Voici comment vous pouvez essayer par vous-même.

Dans Instruments et avec l’automate sélectionné, recherchez le bouton d’enregistrement en bas de la fenêtre..


Si vous cliquez sur le bouton d’enregistrement, Instruments lancera une session d’enregistrement, comme indiqué dans la capture d'écran ci-dessous..


Instruments lancera votre application dans le simulateur iOS et vous pourrez y interagir. Les instruments généreront un script basé sur vos interactions en temps réel. Essaie. Faites pivoter le simulateur iOS, appuyez sur des emplacements aléatoires, effectuez un geste de balayage, etc. C'est un moyen très utile pour vous aider à explorer les possibilités de l'automatisation d'interface utilisateur..

Éviter une base de code monolithique

Comme vous pouvez probablement le prévoir, si nous continuons à ajouter plus de tests au fichier de test que nous avons créé avec la même méthode, il deviendra rapidement difficile à maintenir. Que pouvons-nous faire pour empêcher cela? Dans mes tests, je fais deux choses pour résoudre ce problème:

  • Un test pour une fonction: Cela implique que les tests que nous écrivons doivent être axés sur une fonctionnalité spécifique. Je vais même lui donner un nom approprié, tel que testEmptyInputField.
  • Regrouper les tests dans un fichier: Je groupe également des tests connexes dans le même fichier. Cela permet de garder le code dans un fichier gérable. Cela facilite également le test de différentes fonctionnalités en exécutant les tests dans un fichier spécifique. De plus, vous pouvez créer un script maître dans lequel vous appelez les fonctions ou les tests que vous avez regroupés dans d'autres fichiers de test..

Dans l'extrait de code suivant, nous importons un fichier JavaScript, ce qui nous permet d'accéder aux fonctions de ce fichier JavaScript..

#import “OtherTests.js”

Conclusion

Dans ce didacticiel, vous avez appris la valeur des tests de niveau supérieur et expliqué comment UI Automation peut aider à combler cette lacune. C'est un autre outil de votre boîte à outils pour vous aider à expédier des applications fiables et robustes.

Références

Référence JavaScript UI Automation