· Tech watch

Selenium, testez fonctionnellement vos applications web (partie 2/2)

Suite de notre épopée sur Selenium, l’outil de test fonctionnel pour des applications web. Pour ceux qui auraient raté l’épisode 1 : art825.

Ce second volet suppose que vous avez lu l’épisode 1 et sera davantage axé sur l’implémentation de Selenium IDE et Selenium RC

Pré-requis

Pour Selenium IDE :

Pour Selenium RC :

  • Java Runtime Environment (JRE) >= 1.5.0 – Téléchargement
  • Selenium RC >= 0.9.2 – Téléchargement
  • Si vous comptez utiliser des scripts en Python, Ruby, Java, PHP, .Net ou Perl, il faut que le langage désiré soit installé sur votre ordinateur afin que les tests puissent être exécutés.

Enregistrer un test

Il suffit de procéder de la façon suivante :

  • Lancer Firefox
  • Menu Outils > Selenium IDE
  • Vérifier que le bouton d’enregistrement (bouton rond rouge) est bien pressé
  • Dans votre fenêtre Firefox, rendez-vous sur la page à tester
  • Exécuter les différentes étapes de votre scénario
  • Une fois votre scénario fini, stopper l’enregistrement en cliquant sur le bouton rond rouge)
  • Sauvegarder votre test (au format HTML)
  • Lancer le pour valider son bon fonctionnement (en cliquant sur la flêche verte)

Si besoin, fignoler votre test :

  • Ajouter des commandes « pause” si Selenium va plus vite que votre application ou détecte mal la fin de chargement de la page
  • Ajouter les commandes Selenium nécessaires si certaines parties de votre test n’ont pas pu être enregistrées par Selenium IDE (cas de certains menus/formulaire avec du javascript)

Utiliser des valeurs dynamiques

Le besoin d’avoir des valeurs dynamiques se fait rapidement sentir dès lors que :

  • l’unicité d’une information est mise en place : une fois le test joué, on ne peut plus le rejouer sous peine de lever une erreur. Dans ce cas, le besoin peut être par exemple de pouvoir générer des listes de noms, prénoms et adresses email.
  • des mécanismes de cache sont en place : une fois le test joué, l’application a stocké les données demandées dans son cache. Rejouer le test est possible mais ce mécanisme de cache peut influer sur les résultats. Dans ce cas, le besoin peut être par exemple de pouvoir générer des dates aléatoires
  • des mécanismes temporels sont en place : si je teste une application de réservation de place de concerts avec pour date le 13 juin 2007, alors le test ne sera plus valide dès le 14 juin, puisque la date de l’événement sera passée.

Selenium nous permet de définir des valeurs dynamiques, utilisables dans nos cas de test en créant des fonctions JavaScript.

Pour ce faire, il faut créer un fichier ‘user-extensions.js’ qui contiendra par exemple pour la définition d’un jour et d’un mois compris entre aujourd’hui et la fin de l’année (les fonctions peuvent être améliorées, nous ne sommes pas à l’abri d’un 31 novembre par ex) :


function RandomNumber(value)
<em>return Math.floor(Math.random()*value) ;
</em>

function RandomDay()
<em>date = new Date() ;
day = date.getDate() ;
return RandomNumber(31-day)+day ;
</em>

function RandomMonth()
<em>date = new Date() ;
month = date.getMonth() ; //janvier = 0 -> décembre = 11
return RandomNumber(11-month)+month ;
</em>

Il faut ensuite déclarer ce fichier dans Selenium IDE : Menu Option > Options… > Extensions de Selenium Core (user-extensions.js). Une fois votre fichier sélectionné, il vous faudra relancer votre instance de Selenium IDE pour qu’il soit pris en compte. Si votre fichier contient une erreur de syntaxe, Selenium IDE vous le dira.

Dans votre test Selenium, remplacez alors la valeur fixe par l’appel à la fonction javascript :

Ce que vous aviez initialement :

| Commande | Cible | Valeur |
| type | Jour_arrivee | 22 |
| type | mois_arrivee | 12 |

Ce que vous obtenez au final :

| Commande | Cible | Valeur |
| type | Jour_arrivee | javascriptRandomDay() |
| type | mois_arrivee | javascriptRandomMonth() |

Dans le cas d’une liste déroulante, il faudra procéder en deux étapes :

  • Génération de la valeur,
  • Selection de la valeur obtenue dans la liste.

| Commande | Cible | Valeur |
| store | mon_jour_arrivee | javascriptRandomDay() |
| select | Jour_arrivee | label=$mon_jour_arrivee |

Conseils :

  • Créer une bibliothèque commune de fonctions JavaScript que chaque testeur/développeur viendra enrichir
  • Décomposer au maximum vos fonctions afin de pouvoir réutiliser rapidement certains morceaux pour construire d’autres fonctions.

{{Construire une {Test Suite }}}

Une Test Suite est un fichier HTML dans lequel chaque test est référencé dans une ligne du tableau, comme vous pouvez le constater dans l’exemple suivant :


<html>
<head>
<meta content="text/html ; charset=UTF-8" http-equiv="content-type">
<title>Selenium : CA Technical Meeting</title>
<script language="JavaScript" type="text/javascript">
var DISABLED = true ; // used to flag failing tests

function filterTestsForBrowser() <em>var suiteTable = document.getElementById("suiteTable") ;
var skippedTests = document.getElementById("skippedTests") ;

for(rowNum = suiteTable.rows.length - 1 ; rowNum >= 0 ; rowNum--)
{
var row = suiteTable.rows[rowNum] ;
var filterString = row.getAttribute("unless") ;
if (filterString && eval(filterString))
{
var cellHTML = row.cells[0].innerHTML ;
suiteTable.deleteRow(rowNum) ;

var newRow = skippedTests.insertRow(1) ;
var newCell = newRow.insertCell(0)
newCell.innerHTML = cellHTML ;
</em>
}
}

function isFileURL() <em>var p = window.location.protocol ;
var result = ("file :" == p) ;
return result ;
</em>
</script>
</head>
<body onload="filterTestsForBrowser()">
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium">
<tbody>
<tr>
<td><b>Selenium : Test Suite</b></td>
</tr>
<tr>
<td><a target="testFrame" href="file:///chemin/des/tests/test1.html">Test 1</a></td>
</tr>
<tr>
<td><a target="testFrame" href="file:///chemin/des/tests/test2.html">Test 2</a></td>
</tr>
</tbody>
</table>
<br />
<em>Not supported in this suite</em>
<table id="skippedTests" cellpadding="1" cellspacing="1" border="1" class="selenium">
<tbody>
<tr>
<td><b>Skipped Tests</b></td>
</tr>
</tbody>
</table>
</body>
</html>
<code>

Le bloc qui nous intéresse particulièrement est :

<code class="html">
<tr>
<td><a target="testFrame" href="file:///chemin/des/tests/test1.html">Test 1</a></td>
</tr>

A noter :

  • La référence au test se fait sous la forme d’un lien.
  • Le test doit avoir la référence target= »TestFrame » pour qu’il puisse être lancé.
  • Il vous suffit d’ajouter autant de ligne dans votre tableau que vous avez de tests à intégrer dans votre Test Suite.

{{Executer une {Test Suite depuis Selenium IDE}}}

Vous pouvez lancer une Test Suite depuis Selenium IDE en utilisant Test Runner. Pour cela il vous suffit de cliquer sur l’icône suivante :

Dans votre navigateur, une fenêtre s’est alors ouverte et elle est composée de 4 parties :

  • En haut à gauche, la zone contenant le détail de votre Test Suite
  • En haut au milieu : le contenu de votre cas de test
  • En haut à droite : le panneau de contrôle de Test Runner
  • En bas : un aperçu du site dans lequel est exécuté votre test.

Pour que TestRunner prenne votre Test Suite en considération, il vous suffit de changer le contenu de la variable « test » dans l’url appelée. Une fois votre Test Suite chargée, il vous suffit de l’exécuter.

Exporter un test vers Selenium RC

Comme dit dans le précédent billet, un des intérêts de Selenium RC est de pouvoir exécuter des tests dans un langage de script. Ce langage permettant de réaliser des actions supplémentaires, impossibles à réaliser depuis Selenium IDE.

L’export se fait très simplement :

  • Fichier > Exporter le Test sous > Choisissez le format qui vous intéresse.
  • Sauver le fichier avec l’extension appropriée.

Optionel : vous aurez peut être besoin de modifier la valeur de la « base url » dans votre test. Par défaut, Selenium IDE considère que cela est « localhost », ce qui peut ne pas correspondre à votre environnement.

Ex pour un test exporté en python :

Avant :

self.selenium = selenium("localhost", 4444, "*iexplore", "http://localhost:4444") ?

Après :

self.selenium = selenium("localhost", 4444, "*iexplore", "http://test.server.tld") ?

Exécuter un test avec Selenium RC

Il vous faut d’un côté lancer le serveur Selenium RC :

java –jar c :\path\to\selenium-rc\selenium-server.jar

et de l’autre lancer votre fichier de test dans votre langage de script (ou de double-cliquer sur le fichier si votre système d’exploitation vous le permet) :

C :\path\to\your\language\language.exe c :\path\to\test\test_case.ext

Note : si votre test utilise les fonctions javascript définies dans user-extensions.js, il vous suffit d’ajouter le paramètre « –userExtensions c :\path\to\user-extensions.js » lors du lancement du serveur :

java –jar c :\path\to\selenium-rc\selenium-server.jar -userExtensions c :\path\to\user-extensions.js

{{Exécuter une {Test Suite avec Selenium RC}}}

Pour se faire, il vous suffit le serveur en utilisant le paramètre htmlSuite et de préciser :

  • le navigateur à utiliser parmi *chrome (firefox) et *iehta (Internet Explorer)
  • l’url à tester,
  • le chemin de votre Test Suite
  • le chemin où stocker les résultats de la Test Suite :

java –jar c :\path\to\selenium-rc\selenium-server.jar –htmlSuite *iehta http://your.server.tld c :\path\to\test\suite\YourTestSuite.html c :\path\to\results.html

De la même façon que précédemment, si vous devez utilser vos fonctions javascript, il faut ajouter le paramètre userExtensions :

java –jar c :\path\to\selenium-rc\selenium-server.jar –htmlSuite *iehta http://your.server.tld c :\path\to\test\suite\YourTestSuite.html c :\path\to\results.html -userExtensions c :\path\to\user-extensions.js

Exécuter des tests en parallèle avec Selenium RC

Il suffit de :

  • lancer autant d’instances de Selenium RC que nécessaire sur différents ports (en utilisant le paramètre « –port »
  • Adapter vos scripts pour qu’ils utilisent le port en question au lieu du port par défaut (4444) ?
  • Exécuter les scripts.

selectAndWait vs select

Dans le cas de formulaire avec des listes déroulantes conditionnelles, il se peut que votre test échoue si vous cherchez à selectionner la valeur par défaut d’une liste rafraichie par la liste précédente.

Cela s’explique par le fait que Selenium enregistre votre selection via la commande « SelectAndWait ». Comme vous sélectionnez la valeur par défaut d’une liste, Selenium ne voit pas cet événement et attend en vain.

L’astuce consiste alors à remplacer « selectAndWait » par « select ».

Ressources

Selenium IDE

Selenium RC

Nous arrivons au terme de ce second épisode sur Selenium. Le but était d’illustrer son fonctionnement au travers de différents exemples. Toutes les fonctionnalités de l’outil n’ont pas été présentées ici (exécution d’un test pas à pas, définition de nouveaux point de démarrage d’un test, etc), l’idée étant de faire avant tout une présentation rapide de l’outil. Il ne vous reste plus qu’à jouer avec pour mieux l’appréhender.

11 commentaires

  1. Denis Fingonnet

    Outil intégré dans mes process qualité ! Merci Nico

  2. Antony GUILLOTEAU

    Bonjour,

    Aujourd’hui nous n’assurons pas compatibilité de nos applications sous Fire Fox mais sous IE. Avez-vous une solution similaire à Selenium IDE pour IE ?

    En tout cas mes félicitations pour la qualité des ces deux articles.

  3. Nicolas Steinmetz

    Merci !

    Pour des solutions similaires sous Internet Explorer mais que j’avais jugé moins riches que Selenium IDE lors de mes évaluations :
    -* Sahi – Je l’avais éliminé car les logs n’étaient pas directement consultables et surtout que les accents étaient mal/pas gérés.
    -* Watir – Mais il manquait un « enregistreur de scénario ». Il fallait écrire tout ses tests soit même en Ruby.
    En tout cas mes félicitations pour la qualité des ces deux articles.

    Pour le client chez qui j’ai fait cette étude, IE était le navigateur cible. L’idée était d’enregistrer les tests sous Firefox, puis de les faire exécuter sur IE via le Selenium RC. C’est sur que cela requiert que votre application soit a minima compatible avec Firefox.

  4. Jean-Michel Raoust

    Je fais du test de logiciel WEB avec Selenium IDE. Je suis en train de me constituer un ensemble de tests afin de valider l’application lors d’evolutions futures.
    J’utilise Selenium IDE pour enregistrer un test; tout va bien.
    Quand je rejoue le test il s’arrete sur la ligne suivante:

    clickAndWait link=Voir DIA notaire

    et m’affiche le message d’erreur suivant

    # [info] Executing: |clickAndWait | link=Voir DIA notaire | |

    # [error] Element link=Voir DIA notaire not found

    Quelqu’un a t il une idée ?

    Merci d’avance

  5. Nicolas Steinmetz

    De mon expérience et sans connaître votre application, quelques pistes :
    -* Avez-vous des frames dans votre page ? Si oui, il faut vous placer dans la bonne frame en insérant une commande selectWindow avant la commande clickAndWait.
    -* Si la page n’est pas chargée assez vite, il se peut que l’action clickAndWait arrive trop tôt. Je vous conseille alors d’insérer une commande « pause » de quelques secondes pour être sur que la page soit chargée.

    Nicolas

  6. @Jean michel Raoust

    Peut etre un problème avec les espaces ?

  7. c étais court mais intéressant merci .

  8. Hello,
    Merci pour ton article très clair.
    J’ai une question : le serveur linux surlequel je souhaite installer le RC ne possède pas d’interface graphique. Je m’y connecte en utilisant une connexion SSH.

    Est-ce que tu penses que je peux tout de même installer Firefox sur ce serveur afin que le RC s’appuie dessus en sachant qu’il n’y a pas d’environnement graphique sur le serveur ?

    Pour info, je vais scripter mes test en PHP avec PHPUNIT.

  9. merci, trèes bon tutoriel

  10. Très bonne introduction !

    J’ai découvert un peu tard cet outil qui est vraiment un excellent compromis entre l’usine à gaz de tests et les tests ‘à la mano’.

    Certes, il a aussi ses limites mais il permet avec finalement peu de moyens de s’assurer d’une bonne couverture sur des tests de non régression d’applis web. Il ne se substituera jamais à des tests fonctionnels réalisés par des recetteurs mais quel gain de temps sur les tests récurrents !

    En creusant un peu, on peut se monter (par exemple avec excel) une petite solution d’export des rapports de façon à obtenir un résultat ‘présentable’. En effet, l’outil ne possède pas de fonctions d’export ou de visualisation des résultats.

    En tous cas je le recommande vraiment à un public de développeurs mais aussi volontiers à des recetteurs plus fonctionnels qui pourront aisément s’approprier l’outil via Selenium IDE.

  11. Quel est l’intérêt de la function filterTestsForBrowser dans le testsuite ? celle-ci n’est pas native dans selenium IDE ? De même pour isfileURL ?

    Merci.

Les commentaires sont désormais fermés.