Test de l'interface utilisateur: vérification du système à différentes résolutions

Tester de longs formulaires Web dans divers navigateurs et dans des résolutions est non seulement extrêmement nécessaire, mais aussi pour la troisième ou la quatrième fois - un processus extrêmement ennuyeux et très concentré. C'est donc exactement le domaine qui demande lui-même l'automatisation. C'est ce que nous avons fait.

Dans cet article sur Habr, nous parlerons de notre expérience dans le test de grands écrans avec des outils de grille Protractor, Zalenium et Selenium. Comment nous avons progressivement introduit ces outils pour les tests automatiques de l'interface utilisateur et quelles difficultés nous avons dû traverser.



Nous créons et maintenons un système dans lequel 7 mille utilisateurs actifs. Le plus souvent, ils utilisent ces navigateurs:



Et les résolutions d'écran suivantes:



Chaque fois après la sortie d'une nouvelle version, vous devez vérifier les performances de ces navigateurs et autorisations.

Pour mieux comprendre le fonctionnement habituel des tests d'interface utilisateur dans notre cas, considérons un cas simple: tester la fonctionnalité d'une application pour la récupération de mot de passe. En conséquence, il y a deux pages. Sur l'un, vous devez spécifier un nom d'utilisateur ou un e-mail où une lettre viendra avec un lien vers un changement de mot de passe. Après l'envoi de la demande, l'utilisateur accède à la page avec confirmation que tout s'est bien passé.


Formulaire de récupération de mot de passe


La page vers laquelle la redirection se produit après la soumission réussie de la demande

Le test de ce mécanisme sous une forme simplifiée ressemble à ceci:



Le même script que le code:

it('    ', async function(): Promise<boolean | void> { await browser.get(browser.baseUrl); await element(by.name('EmailOrLogin')).sendKeys(userLogin); await element(by.buttonText('')).click(); const screenshot = await browser.takeScreenshot(); const canonicalScreenshotPath = <   >; await compareScreenshot(screenshot, canonicalScreenshotPath); }); 

Comme vous pouvez le voir, le code de test semble assez simple, il répète littéralement ce qui était montré sur le diagramme.

Nous montrons maintenant quels outils ont été utiles pour implémenter ce schéma à différentes résolutions d'écran, et quelles difficultés nous avons rencontrées.

Boîte à outils sélectionnée


Commencé avec le chrome


Pour l'automatisation des tests, nous avons choisi Protractor, un framework e2e pour tester les applications angulaires. Notre application est juste sur Angular. Avec Protractor, nous avons fait deux types de tests:

  1. Sur la fonctionnalité générale: Un formulaire de soumission de candidature est ouvert, rempli avec des données et une candidature est envoyée, après quoi nous vérifions qu'une redirection vers le registre de toutes les candidatures s'est produite.
  2. Tests de capture d'écran: Protractor vous permet de prendre une capture d'écran à tout moment. En utilisant une bibliothèque séparée de récolte bleue, nous avons comparé deux captures d'écran: une référence et une vraie. S'ils ne correspondent pas, une capture d'écran est immédiatement créée sur laquelle toutes les différences sont visibles, tout comme dans Git.

Par exemple, si vous continuez d'analyser l'exemple décrit ci-dessus.


Capture d'écran avec un message de lien non valide


Les différences (texte et disposition du bouton) dans les captures d'écran de référence et actuelles sont mises en évidence en lilas

Si la page contient des données à changement dynamique (par exemple, la date ou le numéro de commande), vous devez les masquer - cette fonctionnalité se trouve dans la bibliothèque de récolte bleue. Sinon, la comparaison des captures d'écran donnera un résultat négatif.

Ajouter FF et différentes autorisations


Au fil du temps, nos exigences pour le système de test d'interface utilisateur existant ont augmenté:

  • exécuter des tests non seulement dans Chrome, mais aussi dans FF,
  • effectuer des tests de capture d'écran non pas sur une résolution, mais sur les plus populaires,
  • exécuter des tests en parallèle.

Faisons donc exécuter nos tests en parallèle dans Chrome et FF.

Pour ce faire, dans la configuration des capacités de Protractor'a, remplacez-la par ceci:

 multiCapabilities: [ { shardTestFiles: true, maxInstances: 2, browserName: 'chrome' }, { shardTestFiles: true, maxInstances: 2, browserName: 'firefox' } ] 

Tout est évident ici, dont chaque cadre est responsable. Ne mérite que l'attention
shardTestFiles: true
/** * If this is set to be true, specs will be shared by file (ie all files to be run by this set of capabilities will run in parallel). * Default is false. */

Avec cet indicateur, nous fournissons le lancement parallèle de toutes les spécifications dans tous les navigateurs qui sont spécifiés dans multiCapabilities.

Le paramètre specs est caché sous le mot specs, qui détermine par quel modèle rechercher des fichiers avec des tests.

 exports.config = { ... specs: ['./e2e/**/*.spec.ts'], ... } 

La théorie de la division de tous les tests en plusieurs fichiers de spécifications semble assez logique. la concurrence fonctionne sur eux (par exemple, créez un fichier de spécifications pour chaque fonctionnalité de l'application).

De plus, dans Protractor'e, il est possible de mettre en valeur les suites.

 exports.config = { ... suites: { suite01: './e2e/**/suite01.*.spec.ts', suite02: './e2e/**/suite02.spec.ts', suite03: './e2e/**/suite03.spec.ts' }, ... } 

Comme vous pouvez le voir dans cette partie de la configuration, lors du démarrage d'une suite, les tests sont exécutés à partir d'un seul fichier de spécification. Ceci est probablement utile si vous souhaitez exécuter des tests pour une seule partie de l'application.

En ce qui concerne le test de l'application à différentes résolutions, nous avons suivi le chemin suivant. En tant qu'autorisations expérimentales, l'une des plus populaires a été sélectionnée: 1920x1080, 1366x768, 1440x10900, 768x1024. Lorsque vous exécutez chaque test, toutes les actions nécessaires ont été initialement effectuées, puis une série de vérifications de capture d'écran est effectuée.



Nous connectons IE et des captures d'écran en taille réelle


Les tests de capture d'écran que nous avons obtenus, malheureusement, n'ont fonctionné que sur la base de la partie initialement visible de la page. Et si le défilement était présent sur la page, alors tout ce qui était ci-dessous restait inexploré pour la mise en page.

En plus de cela, nous devons également prendre en charge IE, pour lequel nos tests n'ont pas encore été conçus. Nous avons commencé à chercher une opportunité adéquate pour exécuter des tests dans IE et prendre des captures d'écran en taille réelle.



Nous avons opté pour deux solutions: Zalenium et Selenium-Grid . Nous omettons la description de ce que l'un d'eux se vante de quoi et racontons ce qu'il a trouvé / n'a pas trouvé dans l'une ou l'autre solution.

Zalenium : cette solution s'exécute dans un conteneur Docker et N autres conteneurs montent après le conteneur principal - pour lancer les navigateurs. Vous permet de spécifier screenWidth, screenHeight pendant l' docker run menu fixe et d'obtenir la taille de l'écran, par exemple, 1920x6000. Il n'y a pas de support pour IE.


Deux navigateurs avec une taille d'écran de 1920x6000

Grille de sélénium: les tests dans IE ont commencé très facilement.
Parmi les inconvénients: il n'y a aucun moyen de définir la taille de la fenêtre du navigateur de n'importe quelle taille.

Total: grille Zalénium + Sélénium
Nous nous sommes installés sur un tas de grille Zalenium + Selenium: via Zalenium, il a été décidé d'exécuter des tests dans Chrome et FF, et via Selenium-grid pour vérifier les performances minimales de l'application dans IE.

Ce qui était intéressant à rencontrer dans le processus


1. Utilisation de formControlName comme localisateur d'élément

En utilisant la recherche sur formControlName, vous pouvez facilement rechercher les champs requis sur le formulaire et les remplir avec des données de test. Le localisateur de formControlName n'est pas intégré, mais il est facile d'ajouter:

 exports.config = { ... onPrepare() { require('ts-node').register({ project: 'e2e/tsconfig.e2e.json' }); jasmine.getEnv().addReporter(new specReporter({ spec: { displayStacktrace: true } })); addFormControlNameLocator(protractor); } ... } function addFormControlNameLocator(protractor) { protractor.by.addLocator('formControlName', function(value, optParentElement) { var using = optParentElement || document; return using.querySelectorAll('[formControlName="' + value + '"]'); }); } 

2. La différence dans le travail du webdriver-manager installé globalement et localement dans Protractor

Lors de l'installation de Protractor dans le système (la documentation officielle conseille d'installer Protractor à l'échelle mondiale), en plus du cadre de test lui-même, nous obtenons le gestionnaire de pilotes Web installé, qui fournit des pilotes aux navigateurs pour exécuter des tests, avec lesquels l'un des problèmes a été détecté.

Après avoir accédé au dossier du projet et exécuté la mise à jour du gestionnaire de pilotes Web, les pilotes pour Chrome, FF, IE sont téléchargés. Après cela, lors du démarrage des tests, ils ont détecté l'erreur:

No update-config.json found. Run 'webdriver-manager update' to download binaries.

Nous avons réalisé que l'erreur disparaît si nous emballons la mise à jour du gestionnaire de pilotes Web dans un script npm:

 { ... scripts:{ “webdriver-update”: “webdriver-manager update” } ... } 

et exécutez via npm run webdriver-update , les sources du pilote et le fichier update-config.json mentionné ci-dessus entrent dans le dossier du projet.

3. Exécuter Zalenium via docker-compose

La documentation de Zalenium est accompagnée d'exemples de la commande docker run et du fichier docker-compose. Tout décolle presque comme par magie. Le seul problème que nous avons rencontré s'est produit lors du démarrage du fichier docker-compose
/var/run/docker.sock is not a valid windows path . La solution est .

4. Visibilité des éléments par le rapporteur

Au cours de nos expériences, à un moment, nous avons été confrontés à la tâche de percer un menu sur la page, c'est-à-dire allez à chaque page du menu et faites une capture d'écran.



Après avoir traité le premier élément de la liste, les tests ont commencé à tomber, lançant une erreur selon laquelle il n'y avait rien à cliquer sur certaines coordonnées. Il s’est avéré que, malgré le fait que tous les éléments de la liste aient été initialement sélectionnés, après qu’ils soient devenus vraiment invisibles à nos yeux, ils ont disparu aux yeux de Protractor.

Nous avons résolu le problème en définissant une largeur d'écran suffisante pour que le menu réapparaisse avant de cliquer sur son élément suivant.

5. Changement de résolution dans IE (grille de sélénium)

Comme vous vous en souvenez, dans Chrome et FF, nous avons affiné le changement de résolution d'écran. Lorsqu'il s'agit de cela dans IE, nous avons simplement détecté l'erreur: Failed: java.io.IOException: Server returned HTTP response code: 405 for URL: http://localhost:21800/session/8d14426d-6483-4bbf-90b3-2a3ed46ebe9b/window/size .

Après un long débogage, il a été possible de découvrir que l'erreur vole exactement au moment où le code tente d'exécuter: browser.driver.manage().window().setSize(x, y) . Si vous essayez d'exécuter browser.driver.manage().window().setPosition(x, y) , puis détectez la même erreur, seule la taille changera en position. Cela nous amène au fait qu'il est impossible de contrôler la résolution d'écran lorsque les tests sont exécutés dans IE. La solution au problème est des béquilles avec lesquelles vous devez superposer votre code afin de ne pas changer la résolution \ position lorsque IE est en cours d'exécution.

6. Zalenium et WebSocket

Après avoir collecté toutes les bosses localement, il a été décidé d'intégrer Zalenium dans l'infrastructure de l'entreprise. Le conteneur est ouvert, DNS est enregistré, maintenant tout le monde peut exécuter des tests dans Zalenium, simplement en spécifiant le chemin d'accès dans sa configuration Protractor. La beauté, hein? Mais ça y était.

Dans ce cas, tout était déjà déployé sur la machine Linux, Nginx était utilisé comme serveur. Le conteneur avec Zalenium est monté sans problème, suivi par un autre N conteneurs pour lancer les navigateurs, mais ... n'a pas pu établir de connexion avec eux. Il était facile de constater que le conteneur parent tentait de communiquer avec les conteneurs des navigateurs via le protocole WebSocket, et Nginx ne pouvait pas le faire par défaut. Le traitement est très simple.

 location / { proxy_pass some_url; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; } 

9. Lancement de Selenium-Grid

Pour exécuter Selenium-Grid, nous avons besoin de:

  • serveur sélénium ,
  • Pilote IE, qui est facile à obtenir via la mise à jour du gestionnaire de pilotes Web --ie32.

lancement du serveur:

java -jar selenium-server-standalone.jar -role hub -hubConfig selenium-server-config.json

 selenium-server-config.json { "host": "127.0.0.1", "maxSessions": 5, "port": 4445, "cleanupCycle": 5000, "timeout": 300000, "newSessionWaitTimeout": -1, "servlets": [], "prioritizer": null, "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher", "throwOnCapabilityNotPresent": true, "nodePolling": 180000, "platform": "WINDOWS" } 

lancement du pilote IE:

java -Dwebdriver.ie.driver=< > -jar selenium-server-standalone.jar -role node -nodeConfig .\\ie-driver-config.json

 ie-driver-config.json { "capabilities": [ { "browserName": "internet explorer", "maxInstances": 1, "platform": "WINDOWS", "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe" } ], "cleanUpCycle": 2000, "timeout": 30000, "port": -1, "role": "node", "hub": "http://127.0.0.1:4445/grid/register/", "register": true, "maxSessions": 5 } 

Faites attention à l'utilisation des mêmes ports lors du démarrage du serveur et dans l'URL du concentrateur du pilote. En tant que seleniumAddress dans la configuration du rapporteur, nous utilisons http://127.0.0.1:4445/wd/hub .

Conclusions


Nous avons donc résolu notre tâche et à chaque fois après la sortie d'une nouvelle version, nous pouvons vérifier les performances dans ces navigateurs et résolutions.

Comment intégrer des tests dans un workflow


Il est important de comprendre qu’il ne suffit pas de soulever toute l’infrastructure pour exécuter des tests et les écrire. Vous devez réfléchir à la façon dont vous les utiliserez dans votre vie quotidienne.

Nous n'avons pas implémenté de tests d'interface utilisateur dans CI, car ils sont exécutés assez longtemps pour se permettre d'attendre leur exécution pour chaque build.

Pour tester la version locale de l'application ou installée sur l'un des environnements de test (interne ou client), il suffit de changer baseUrl dans la configuration Protractor'a. Par conséquent, les tests peuvent être exécutés par le développeur et le testeur.
Développeur - lorsqu'il est nécessaire d'exécuter des tests, par exemple, pour la version locale de l'application en cours de développement d'une nouvelle fonctionnalité. Spécialiste en assurance qualité - par exemple, comme test de fumée après un déploiement sur la prod, ou comme contrôle sur le dessus après un tas de refactoring.

En conclusion, nous voulons souligner:

  • N'oubliez pas que les tests d'interface utilisateur ne vous éviteront pas de devoir effectuer des tests manuels détaillés. L'automatisation permet uniquement de couvrir des zones.
  • Utilisez l'automatisation à bon escient, principalement pour les tests de fumée. Couvrir tout et tout n'a aucun sens - c'est cher et difficile de se tenir à jour
  • Écrivez simplement. si vos tests d'interface utilisateur semblent compliqués, vous faites quelque chose de mal. Battre simple et utiliser comme indiqué (voir point 2)

Nous pensons que l'automatisation des tests d'interface utilisateur est bonne lorsqu'elle est effectuée facilement. Alors partagez avec nous vos observations et outils réussis dans les commentaires.

Liens utiles de notre part:


Source: https://habr.com/ru/post/fr425647/


All Articles