Accueil » Webmastering » Création site web » Éditeurs de site » Test automatisé des navigateurs avec l’API WebDriver

Test automatisé des navigateurs avec l’API WebDriver

Le fait de cliquer manuellement sur différents navigateurs lorsqu’ils exécutent votre code de développement, localement ou à distance, est un moyen rapide de valider ce code. Il vous permet d’inspecter visuellement que les choses sont telles que vous les attendiez du point de vue de la mise en page et de la fonctionnalité. Cependant, ce n’est pas une solution pour tester l’intégralité de la base de code de votre site sur l’assortiment de navigateurs et de types d’appareils disponibles pour vos clients. C’est là que les tests automatisés prennent tout leur sens.

Mené par le projet Selenium, le test web automatisé est une suite d’outils pour créer, gérer et exécuter des tests sur les navigateurs sur toutes les plates-formes.

API WebDriverJS

L’API WebDriver est un standard qui extrait les liaisons spécifiques au périphérique/navigateur du développeur afin que les scripts de test écrits dans le langage de votre choix puissent être écrits une seule fois et exécutés sur de nombreux navigateurs différents via WebDriver. Certains navigateurs ont des capacités WebDriver intégrées, d’autres nécessitent de télécharger un binaire pour votre combinaison navigateur/système d’exploitation.

Conduire le navigateur via les API WebDriver

La spécification WebDriver du W3C documente les API disponibles pour les développeurs afin de contrôler par programme le navigateur. Ce diagramme présente un exemple de page avec certaines des collections et API WebDriver générales pouvant être utilisées pour obtenir et définir les propriétés du navigateur.

Tests de conception

Vous disposez d’un choix de langages basé sur les liaisons de langages prises en charge pour WebDriver. Les principaux langages pris en charge par le projet principal Selenium/WebDriverJS sont :

  • C#
  • Java
  • JavaScript (via Node)
  • Python
  • Rubis

Les tests peuvent varier depuis la vérification de la mise en page de la page, des valeurs renvoyées à partir des appels côté serveur, du comportement attendu de l’interaction de l’utilisateur à la vérification du flux de travail, par exemple.

À des fins d’illustration, supposons que nous testons l’application TODOMVC, une application de démonstration implémentée dans plusieurs frameworks JavaScript de contrôle de vue de modèle. Cette application simple permet à l’interface utilisateur d’entrer des tâches, d’éditer, de supprimer et de marquer des éléments comme complets. Nous allons utiliser l’exemple basé sur React sur http://todomvc.com/examples/react/.

Nous allons ensuite être en mesure de démontrer l’exécution des tests pour l’exemple React par rapport aux exemples Backbone.js et Vue.js en changeant simplement l’URL.

Pour cette démonstration, nous allons écrire des tests en JavaScript s’exécutant dans un nœud pour :

  1. Ajouter trois éléments à faire et vérifier ce que nous avons tapé a été créé dans un élément à faire.
  2. Modifier cet élément en double-cliquant, en envoyant des commandes clavier en arrière-plan et en ajoutant plus de textes.
  3. Supprimer cet élément en utilisant les API de la souris.
  4. Cocher un élément de la liste comme terminé.

Configurez votre environnement de test d’automatisation de base

Commençons par obtenir la configuration de la machine (pour ce test, on a utilisé Windows 10) pour exécuter WebDriver à l’aide de JavaScript. Les appels à WebDriver à partir du nœud seront presque toujours asynchrones. Pour faciliter la lecture du code, nous avons utilisé async/await de ES2016 sur Promises ou callbacks.

Vous aurez besoin d’installer node.js plus récent que v7.6 ou utiliser Babel pour effectuer une compilation croisée afin de prendre en charge la fonction async/await. En outre, nous utilisons Visual Studio Code pour l’édition et le débogage des nœuds.

WebDriverJS pour Microsoft Edge

Chaque navigateur aura un fichier binaire dont vous aurez besoin localement pour interagir avec le navigateur lui-même. Ce binaire est appelé par votre code via les APIs Selenium WebDriver. Vous pouvez trouver les derniers téléchargements et la documentation pour Microsoft Edge WebDriver ici.

Notez que la version d’Edge sur laquelle vous souhaitez exécuter les tests doit être testée avec la version correspondante de MicrosoftWebDriver.exe. Nous allons utiliser la version stable d’Edge (16.16299) avec la version MicrosoftWebDriver.exe correspondante 5.16299.

Placez MicrosoftWebDriver.exe dans votre chemin ou dans le même dossier que votre script de test sera exécuté. L’exécution de cet exécutable lancera une fenêtre de console affichant l’URL et le numéro de port que WebDriverJS attendra pour gérer les demandes à envoyer.

WebDriverJS pour d’autres navigateurs

Vous pouvez facilement demander à WebDriverJS d’exécuter des tests dans un navigateur différent en définissant une variable de configuration et en installant le pilote binaire approprié pour le navigateur correspondant. Vous pouvez les trouver ici :

Selenium WebDriverJS pour JavaScript

Pour interagir avec le pilote binaire que vous venez de télécharger via JavaScript, vous devez installer la bibliothèque d’automatisation Selenium WebDriver pour JavaScript. Cela peut être facilement installé en tant que paquet de nœud en utilisant :

npm installer selenium-webdriver

Ecriture du code d’automation

Une fois que le binaire du pilote spécifique à votre navigateur se trouve dans le chemin ou le dossier local de votre système et que vous avez installé Selenium WebDriver via npm, vous pouvez commencer à automatiser le navigateur via le code.

Allons décrire notre code d’exemple dans les différentes étapes dont vous aurez besoin.

1. Créez une variable locale pour charger et interagir avec la bibliothèque.

var webdriver = require('selenium-webdriver');

2. Par défaut, WebDriverJS suppose que vous exécutez localement et que le fichier de pilote existe. Plus tard, nous montrerons comment vous pouvez transmettre les informations de configuration dans la bibliothèque lors de la première instanciation du navigateur. WebDriverJS est instancié avec une variable de configuration appelée « capabilities » pour définir le pilote de navigateur que vous souhaitez utiliser.

var capabilities = {
 'browserName': 'MicrosoftEdge'
 };
 var entrytoEdit = "Browser Stack";

3. Ensuite, vous créez une variable et appelez build () avec la variable de configuration capabilities pour que WebDriverJS instancie le navigateur :

var browser = new webdriver.Builder().withCapabilities(capabilities).build();

4. Maintenant que nous pouvons interagir avec le navigateur, nous lui disons de naviguer vers une URL en utilisant la méthode `get`. Cette méthode est asynchrone, donc nous utilisons `await` pour attendre qu’elle se termine.

// Have the browser navigate to the TODO MVC example for React
 await browser.get('http://todomvc.com/examples/react/#');

5. Pour certains navigateurs et systèmes, il est préférable de laisser au binaire WebDriverJS le temps de naviguer vers l’URL et de charger la page. Pour notre exemple, nous attendons 1 seconde (1000ms) en utilisant la fonction de gestion de WebDriverJS :

//Send a wait to the browser to account for script execution running
 await browser.manage().timeouts().implicitlyWait(1000);

6. Vous avez maintenant un hook programmatique dans un navigateur en cours d’exécution via la variable du navigateur. Notez le diagramme de collection plus haut dans ce document qui montre les collections API WebDriver. Nous utilisons la collection Elements pour obtenir des éléments spécifiques à partir de la page. Dans ce cas, nous recherchons la zone de saisie dans l’exemple TODOMVC afin que nous puissions entrer quelques éléments TODO. Nous demandons à WebDriverJS de rechercher les éléments qui correspondent à la règle de classe .new-todo car nous savons que c’est la classe assignée à ce champ. Nous déclarons une constante car nous ne pouvons pas changer les données qui reviennent. Notez que ceci trouvera le premier élément dans le DOM qui correspond au modèle CSS, ce qui est bien dans notre cas car nous savons qu’il n’y en a qu’un seul.

const todoEntry = await browser.findElement(webdriver.By.css('.new-todo'));

7. Ensuite, nous envoyons des combinaisons de touches au champ que nous venons de gérer avec la fonction sendKeys. Nous mettons la clé d’entrée échappée sur sa propre ligne d’attente pour éviter les conditions de course. Nous utilisons le modèle d’itération for (x of y) car nous traitons des promesses. toDoTestItems est simplement un tableau de 3 chaînes, une variable chaîne (que nous testerons plus tard) et 2 littéraux. Sous les couvertures, WebDriverJS enverra les caractères individuels de la chaîne un à la fois, mais nous passons simplement la variable chaîne entière à sendKeys :

var toDoTestItems = [entrytoEdit, "Test Value1", "Test Value2"];
 //Send keystrokes to the field we just found with the test strings and then send the Enter special character
 for (const item of toDoTestItems) {
 await todoEntry.sendKeys(item);
 await todoEntry.sendKeys("\n");
 }

À ce stade, exécutons le script avec le nœud et allons voir si nous voyons un navigateur qui accède à la page et entre ces trois éléments TODO de test. Enveloppez le code après la première déclaration de variable dans une fonction asynchrone comme ceci :

async function run() {

Fermez la fonction} à la fin du code, puis appelez cette fonction async avec :

run();

Enregistrez votre fichier JS. Accédez à la fenêtre de commande du nœud, naviguez jusqu’au dossier dans lequel vous avez enregistré le fichier JS et exécutez le nœud yourfile.js

Vous devriez voir une fenêtre de navigateur apparaître et le texte envoyé au fichier TODOMVC doit être entré comme de nouvelles entrées TODO dans l’application. Félicitations – vous êtes opérationnel avec WebDriverJS.

Essayez de modifier l’URL que WebDriverJS charge dans cet exemple par l’un des autres exemples TODOMVC et observez que le même code de test peut s’exécuter sur des frameworks différents.

await browser.get('http://todomvc.com/examples/vue/');

Exécution de tests sur BrowserStack

Nous avons montré comment ce test s’exécute localement sur votre machine. Le même test peut fonctionner aussi facilement en utilisant des services de test en ligne comme BrowserStack. Inscrivez-vous pour un accès gratuit au service BrowserStack afin d’accéder aux navigateurs Microsoft Edge pour des tests gratuits en direct et automatisés. Une fois connecté, accédez à la section « Automatiser » et recherchez vos paramètres de compte de test automatisés. Vous devrez les transmettre à la fonction WebDriverJS pour vous connecter via le code, nommez votre session de test et transmettez votre jeton d’accès.

Ensuite, ajoutez simplement ces valeurs dans la variable « capabilities » et appelez à nouveau le générateur WebDriver.

var capabilities = {
 'browserName': MicrosoftEdge,
 'browserstack.user': 'yourusername’,
 'browserstack.key': 'yqniJ4quDL6s2Ak2EZpe',
 'browserstack.debug': 'true',
 'build': 'Name your test'
 }

Vous pouvez en apprendre plus sur la variable « capabilities » et les valeurs que BrowserStack peut accepter ici.

Appelez ensuite la fonction de générateur et transmettez l’URL du serveur BrowserStack :

var browser = new webdriver.Builder().
 usingServer('http://hub-cloud.browserstack.com/wd/hub').
 withCapabilities(capabilities).
 build();

Enfin, vous devez demander à WebDriverJS de quitter le navigateur, sinon il restera actif et finira par expirer. Placez un appel à la fonction « quitter » à la fin de votre fichier de test.

browser.quit();

Maintenant, lorsque vous exécutez votre fichier de test JS à l’aide de NodeJS, vous allez envoyer les instructions de test à un navigateur hébergé sur le service cloud de BrowserStack. Vous pouvez aller dans la section « Automatiser » de BrowserStack et observer les travaux de test démarrant et s’arrêtant. Une fois terminé, vous pouvez parcourir les commandes WebDriver qui ont été envoyées, voir les images de l’écran du navigateur à intervalles réguliers pendant le test et même voir une vidéo de la session du navigateur.

Une capture d’écran de la fonctionnalité de journal visuel d’un test exécuté sur le service Automatiser de BrowserStack

Test des valeurs avec des assertions

Lorsque vous testez votre site, vous comparez les résultats réels aux résultats attendus. La meilleure façon de le faire est de faire des assertions où une exception sera levée si une condition d’affirmation n’est pas remplie. Dans notre exemple, nous utilisons une bibliothèque d’assertions pour exprimer ces assertions et aider à rendre le code plus lisible. Nous avons choisi ChaiJS, car il est assez flexible pour être utilisé avec n’importe quelle bibliothèque JavaScript et est très populaire au moment de l’écriture.

Vous téléchargez et installez Chai en tant que paquet de nœuds en utilisant npm. Dans le code, vous devez exiger chai :

var expect = require('chai').expect;

Nous avons décidé d’utiliser l’interface Expect pour utiliser un langage naturel pour enchaîner nos assertions.

Vous pouvez tester la longueur, l’existence, qui contient une valeur et bien d’autres.

expect(testElements).to.not.have.lengthOf(0);
 //make sure that we're comparing the right number of items in each array/collection
 expect(testElements.length).to.equal(toDoTestItems.length);

Si l’une de ces assertions n’est pas vraie, une exception d’assertion est levée. Notre exemple de code cessera d’être exécuté lorsque l’exception est levée car nous ne gérons pas l’exception. En pratique, vous utiliserez un test runner avec un nœud qui gérera les exceptions et signalera les erreurs et continue le test.

Automatisation de la continuité de test avec un test runner

Pour mieux gérer les exceptions d’assertion, un test runner est associé à un nœud pour envelopper des blocs de code contenant des assertions de test dans des fonctions de style try/catch qui mappent les exceptions en cas de test échoué.

Dans cet exemple, nous avons choisi le framework de test MochaJS, car il s’accorde bien avec Chai et est utile pour tester le code de production.

Pour intégrer le runner, il y a du code ajouté au script de test et un changement dans la façon dont vous exécutez le code avec le nœud.

Ajout du code du testeur

Vous enveloppez le code de test dans des fonctions asynchrones avec la fonction de niveau supérieur en utilisant le mot clé « describe » et la fonction de sous-test en utilisant le mot clé « it ». Les fonctions sont balisées avec une description de ce que recherchent les tests. Cette description est ce qui sera mappé aux résultats des tests.

MochaJS est installé en tant que paquet de nœud via npm.

Voici la fonction de haut niveau dans notre exemple en utilisant describe :

describe('Run four tests against TODOMVC sample', async () => {

Par la suite, enveloppez vos tests logiques dans des groupes avec le mot-clé it :

it('TEST 3: Delete a TODO item from the list by clicking the X button', async () => {

Les assertions enveloppées dans ces fonctions provoquant une exception seront mappées sur ces descriptions.

Exécution du code avec NodeJS et MochaJS

Enfin, vous devez exécuter votre code de test avec le nœud appelant le binaire MochaJS pour gérer correctement les exceptions. Mocha peut être passé des arguments pour configurer les valeurs de délai, le dossier à rechercher qui contient vos fichiers de test et plus encore. Voici la configuration que nous avons utilisée pour Visual Studio Code pour attacher le débogueur et utiliser l’inspection du Code et parcourir les fonctionnalités :

{
 "type": "node",
 "request": "launch",
 "name": "Mocha Tests",
 "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
 "args": [
 "-u",
 "tdd",
 "--timeout",
 "999999",
 "--colors",
 "${workspaceRoot}/test/**/*.js"
 ],
 "internalConsoleOptions": "openOnSessionStart"
 }

Les tests automatisés sont un excellent moyen de garantir que votre site fonctionne sur différents navigateurs de manière cohérente, sans les tracas ou le coût des tests manuels. Les outils que nous avons utilisés ici ne sont que quelques-uns des nombreux choix disponibles, mais illustrent les étapes communes impliquées dans la configuration et l’exécution de tests automatisés pour vos projets.