- Introduction
- Pré-requis
- Préparation
- Scénario
- Implémentation
- Lancement des tests
- Utilisation de BrowserStack pour l’utilisation de vrai appareils
- Conclusion
La mise en place d’une application web de qualité passe par des tests couvrant un maximum de situations diverses. Savoir créer des tests automatisés permettant de tester des résolutions différentes, des navigateurs différents et le faire sur de vrais appareils permet de couvrir ces utilisations différentes.
Introduction
Dans le monde des PWA et du web responsive, les tests fonctionnels doivent pouvoir tenir compte des différentes utilisations des visiteurs. Cet article a pour but de vous présenter comment créer et lancer des tests pour ces utilisations diverses de vos applications.
Pour cela, nous utiliserons le site https://www.clever-age.com/fr comme exemple.
Beaucoup de frameworks de tests sont disponibles dans de nombreux langages différents (JavaScript, Java, PHP, C#, Python, Ruby, …). Ici nous utiliserons le framework de tests Nightwatch, car il est basé sur Selenium Webdriver qui vient de passer en statut de ‘proposed recommandation’ par le W3C le 26 Avril 2018. De plus son installation et sa configuration sont simples et il est compatible avec BrowserStack et d’autres outils en ligne.
Dans cet article, nous allons créer des tests et les lancer en local sur plusieurs navigateurs et dans plusieurs résolutions. Cela nous permettra de mieux comprendre comment écrire et organiser les tests.
Nous lancerons aussi ces tests sur BrowserStack pour bénéficier de l’utilisation de vrais appareils tels que l’android Pixel ou l’iPhone X.
Pré-requis
Avant de commencer, il vous faut réaliser les opérations suivantes :
- Installer nodeJs https://nodejs.org/en/download/
- Télécharger Selenium Server https://www.seleniumhq.org/download/
- Installer Nightwatch globalement sur la machine http://nightwatchjs.org/gettingstarted#installation
- Télécharger les drivers navigateurs dont vous avez besoin (pour cet article nous utiliserons Chrome, Firefox et Edge)
Préparation
Avant de rentrer dans le vif du sujet, l’écriture des tests, il faut effectuer quelques étapes préparatoires :
- Créer d’un nouveau répertoire projet.
- Récupérer les dossiers npm et nightwatch dans le dossier d’installation de nightwatch (sous windows :C :\Users\[USER]\AppData\Roaming\npm\node_modules) et copier les dans votre répertoire projet. Ces dossiers contiennent tout ce qu’il vous faut pour démarrer les tests (nightwatch bien sûr, la configuration de base, des exemples, …).
- Créer les répertoires suivants à la racine du projet :
- tests (où seront contenus les tests à lancer)
- reports (où les rapports d’exécution seront déposés)
- Selenium (où il faudra déposer le fichier selenium-server-standalone-[VERSION].jar téléchargé plus haut)
- Récupérer le fichier nightwatch.json du dossier ./nightwatch/bin/nightwatch.json et le copier à la racine du projet.
- Copier/coller le driver chrome dans le répertoire “nightwatch/node_module/chromedriver/lib/chromedriver”
- Copier le driver Edge dans le répertoire “nightwatch/node_module/edgedriver/lib/edgedriver”
- Éditer le fichier nightwatch.json
- Renseigner la valeur ‘tests’ pour l’attribut src_folders
- Renseigner la valeur ‘reports’ pour l’attribut output_folder
- Vérifier que les attributs suivants n’ont pas de valeur :
- « custom_commands_path«
- « page_objects_path«
- « custom_assertions_path«
- « globals_path«
- Dans l’objet “selenium” :
- Passer la valeur de l’attribut ‘start_process’ à true
- Renseigner la valeur ‘selenium/selenium-server-standalone-[VERSION].jar’ pour l’attribut ‘server_path’
- Renseigner la valeur ‘nightwatch/node_modules/chromedriver/lib/chromedriver/chromedriver.exe’ de l’attribut ‘webdriver.chrome.driver’ dans l’objet ‘cli_args’
- Renseigner la valeur ‘nightwatch/node_modules/edgedriver/lib/edgedriver/MicrosoftWebDriver.exe’ de l’attribut ‘webdriver.edge.driver’ dans l’objet ‘cli_args’
Dans l’objet ‘test_settings’ : créer des environnements de tests pour chaque navigateur. Pour tester Firefox, Chrome et Edge nous aurons besoin de 3 environnements. L’environnement ‘default’ est utilisé pour Firefox, il faut donc créer les environnements pour Chorme et Edge comme ceci :
"default" : {
"launch_url" : "http://www.clever-age.com",
...
},
"desiredCapabilities" : {
"browserName" : "firefox",
"javascriptEnabled" : true,
"acceptSslCerts" : true
}
},
"chrome" :{
"desiredCapabilities" : {
"browserName" : "chrome",
"javascriptEnabled" : true,
"acceptSslCerts" : true
}
},
"edge" :{
"desiredCapabilities" : {
"browserName" : "MicrosoftEdge",
"javascriptEnabled" : true,
"acceptSslCerts" : true
}
}
Scénario
Nous allons prendre un scénario simple : la vérification des éléments de navigation entre la version desktop et la version mobile du site de Clever Age sur lequel vous lisez cet article.
Nous commencerons par redimensionner la fenêtre du navigateur, puis chargerons la page d’accueil du site de Clever Age pour y faire des tests.
Ces tests vont permettre de vérifier :
- le titre de la page,
- la présence d’éléments dans le DOM,
- la valeur textuelle de certains éléments (Edge renvoyant des valeurs différentes que Chrome et Firefox, j’ai été obligé d’utiliser des regex via la méthode “match” pour m’adapter aux 2 valeurs) et la valeur de certains attributs.
La structure de la page étant différente entre le mode desktop et mobile (burger menu, champ de recherche, …), j’ai créé 2 tests différents qui sont joués indépendamment.
Implémentation
Voici comment j’ai écrit les tests :
Version desktop :
module.exports = {
'clever-age Header Desktop test' : function (browser) {
browser.resizeWindow(1680, 1200) ;
browser.url('https://www.clever-age.com/fr') ;
browser.waitForElementVisible('body', 3000) ;
browser.assert.title('Clever Age - Accueil | Assembleur de cocktails digitaux 100 % indépendant') ;
browser.assert.elementPresent('img.c-svg') ;
browser.verify.elementPresent('#s_0') ;
browser.expect.element('li.lang-item>a').text.to.match(/EN|en/) ;
browser.useXpath() ;
browser.expect.element(".//*[@id='menu-main-menu']/li[1]/a/span").text.to.match(/À propos|À PROPOS/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[2]/a/span").text.to.match(/Métiers|MÉTIERS/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[3]/a/span").text.to.match(/Réalisations|RÉALISATIONS/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[4]/a/span").text.to.match(/CARRIÈRES|Carrières/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[5]/a/span").text.to.match(/VEILLE|Veille/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[6]/a/span").text.to.match(/ACTUS|Actus/) ;
browser.useCss() ;
browser.assert.cssClassPresent("button#searchsubmit","e-btn-search") ;
browser.expect.element('li#menu-item-24058>a>span.menu-item_in-1').to.have.css('color').which.match(/rgb.{1,2}255, 255, 255.{1,4}/) ;
if(browser.expect.element("#s_0").to.be.present){
browser.setValue("#s_0","Test") ;
browser.pause(1000) ;
browser.clearValue("#s_0") ;
browser.setValue("#s_0",["Nightwatch"]) ;
browser.click("#searchsubmit") ;
browser.pause(2000) ;
browser.assert.title('Recherche pour "Nightwatch" - Clever Age') ;
browser.expect.element("h1.txt-single").text.to.match(/Résultats de recherche pour « Nightwatch »|Résultats de recherche pour « Nightwatch »/) ;
}
browser.end() ;
},
} ;
Version mobile :
module.exports = {
'clever-age Header Mobile test' : function (browser) {
browser.resizeWindow(768, 1024) ;
browser.url('https://www.clever-age.com/fr') ;
browser.waitForElementVisible('body', 2000) ;
browser.assert.title('Clever Age - Accueil | Assembleur de cocktails digitaux 100 % indépendant') ;
browser.assert.elementPresent('img.c-svg') ;
browser.verify.elementPresent('#s_0') ;
browser.expect.element('li.lang-item>a').text.to.match(/EN|en/) ;
browser.useXpath() ;
browser.expect.element("//*[@id='nav']/div/div/div[1]/button").text.to.match(/NAVIGATION|Navigation/) ;
browser.click("//*[@id='nav']/div/div/div[1]/button") ;
browser.expect.element(".//*[@id='menu-main-menu']/li[1]/a/span").text.to.match(/À propos|À PROPOS/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[2]/a/span").text.to.match(/Métiers|MÉTIERS/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[3]/a/span").text.to.match(/Réalisations|RÉALISATIONS/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[4]/a/span").text.to.match(/CARRIÈRES|Carrières/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[5]/a/span").text.to.match(/VEILLE|Veille/) ;
browser.expect.element(".//*[@id='menu-main-menu']/li[6]/a/span").text.to.match(/ACTUS|Actus/) ;
browser.useCss() ;
browser.assert.cssClassPresent("button#searchsubmit","e-btn-search") ;
browser.expect.element('li#menu-item-24058>a>span.menu-item_in-1').to.have.css('color').which.match(/rgb.{1,2}255, 255, 255.{1,4}/) ;
browser.isVisible(".field-search", function(searchVisibility){
if(this.verify.equal(searchVisibility.value, true)){
browser.setValue("#s_0","Test") ;
browser.pause(1000) ;
browser.clearValue("#s_0") ;
browser.setValue("#s_0",["Nightwatch",browser.Keys.ENTER]) ;
browser.pause(3000) ;
browser.assert.title('Recherche pour "Nightwatch" - Clever Age') ;
browser.expect.element("body").text.to.contain('Résultats de recherche pour « Nightwatch »') ;
}else{
browser.useXpath() ;
browser.click(".//*[@id='menu-main-menu']/li[1]/a/span") ;
browser.pause(1000) ;
browser.assert.title('À propos de Clever Age') ;
browser.expect.element("//*[@id='main']/div[2]/div/div[1]/div/h2").text.to.match(/Notre indépendance au service de votre transformation digitale|NOTRE INDÉPENDANCE AU SERVICE DE VOTRE TRANSFORMATION DIGITALE/) ;
}
})
browser.end() ;
},
} ;
Hormis les fonctionnalités de base et les clicks pause, assert, verfiy et except, j’ai utilisé des méthodes de sélections d’éléments différentes, Xpath et les sélecteurs CSS. J’ai également utilisé une condition dans la version mobile, me permettant de m’adapter à la présence du champ de recherche et de déclencher une action différente pour compenser.
Lancement des tests
Pour lancer les tests, il vous faut ouvrir un terminal dans le répertoire et lancer la commande suivante :
node .\nightwatch.js -e default,chrome,edge
Le serveur Selenium renseigné démarrera alors et les tests seront lancés sur les 3 navigateurs en même temps.
Des logs des tests seront affichés dans le terminal et un rapport par navigateur sera disponible dans le dossier reports.
Utilisation de BrowserStack pour l’utilisation de vrais appareils
BrowserStack, comme d’autres services, permet de piloter des navigateurs, simulés et réels. Dans notre cas, nous allons tester sur iPhone X et Google Pixel.
Pour cela, créons un nouveau répertoire et copions-y le contenu de notre répertoire précédent. Suivez alors les étapes :
- Renommer le fichier nightwatch.json en nightwatch.conf.js
- Modifier la configuration pour permettre l’utilisation de BrowserStack et de vrais appareils (vous trouverez la liste complète des appareils ici : https://www.browserstack.com/automate/nightwatch)
- Changer les valeurs USER et KEY de la configuration ci-dessous :
nightwatch_config ={ src_folders : ["tests"], output_folder : "reports", selenium : { "start_process" : false, "host" : "hub-cloud.browserstack.com", "port" : 80 }, common_capabilities : { 'browserstack.user' : USER, 'browserstack.key' : 'KEY', 'browserstack.debug' : true }, test_settings : { default : { screenshots : { enabled : true, path : "reports" }, desiredCapabilities : { 'device' : 'iPhone X', 'realMobile' : 'true', 'os_version' : '11.0' } }, androidGalaxyS8 :{ desiredCapabilities : { 'device' : 'Samsung Galaxy S8', 'realMobile' : 'true', 'os_version' : '7.0' } }, androidPixel :{ desiredCapabilities :{ 'device' : 'Google Pixel', 'realMobile' : 'true', 'os_version' : '8.0' } } } } ; // Code to copy seleniumhost/port into test settings for(var i in nightwatch_config.test_settings){ var config = nightwatch_config.test_settings[i] ; config['selenium_host'] = nightwatch_config.selenium.host ; config['selenium_port'] = nightwatch_config.selenium.port ; config['desiredCapabilities'] = config['desiredCapabilities'] || {} ; for(var j in nightwatch_config.common_capabilities){ config['desiredCapabilities'][j] = config['desiredCapabilities'][j] || nightwatch_config.common_capabilities[j] ; } }
module.exports = nightwatch_config ;
- Créer un répertoire à la racine par environnement créé (hors default). Dans notre cas, un répertoire androidGalaxyS8 et un androidPixel dans lesquels seront déposés les tests.
Pour exécuter les tests, il faut lancer les commandes suivantes :
- Dans le sous-répertoire selenium : java -jar .\selenium-server-standalone-[VERSION].jar -port 80
- Dans le répertoire racine : nightwatch -e [ENVIRONNEMENT] (ex : nightwatch -e androidPixel)
L’exécution se lance alors dans BrowserStack : le rapport s’affiche à la fin du déroulement des tests et vous pourrez y voir une vidéo de l’exécution.
Conclusion
Dans ces exemples nous avons pu voir comment mettre en place des tests fonctionnels automatisés sur plusieurs navigateurs dans deux résolutions ainsi que deux mobiles. Nous vérifions la présence d’éléments leurs valeurs ou celles de leurs attributs en fonction des cas. Cela nous donne les bases pour la mise en place de tests sur des projets.
En fonction des projets, il sera peut-être nécessaire d’aller tester l’application dans différents environnements (navigateurs, tailles d’écran, appareils réels). Il faut alors pouvoir mettre en place les tests correspondants.
Vous avez désormais les bases pour vous lancer et élaborer vos tests.
Certains passages sont « atypiques » à cause de la mise en œuvre sur Windows. Une mise à jour de l’article sera effectuée prochainement afin compléter les informations sur autres les environnements.
Digit-U : Développement web Tunisie
23 août 2019
Merci pour cet article pertinent et bien détaillé, qui nous propose plusieurs test intéressants. Bonne continuation.
Isabelle C
19 novembre 2019
article intéressant, cela semble assez facile.
Merci