Selenium

Selenium est un outil qui permet d’effectuer des tests fonctionnels web automatisés sur la plupart des navigateurs, plateformes et languages.

Cet article présente

Si vous êtes impatient vous pouvez aller directement à la vidéo du test Selenium ou au code du test.

Cas d’usage

Pour bien comprendre Selenium, et savoir ce que l’on peut lui demander il est nécessaire de prendre un cas d’usage fonctionnel non trivial qui utilise des composants riches.

Pour cela prenons l’application générée par Celerio que vous pouvez reproduire vous même en ligne et prenons un cas d’usage conséquent.

Objectif

En tant qu’administrateur je souhaite modifier un compte existant, me déconnecter pour ensuite m’identifier avec, puis me déconnecter pour me réidentifier en tant qu’administrateur et remettre enfin le compte modifié dans l’état précédent.

Actions métier

Le chemin fonctionnel souhaité est donc le suivant:

  1. S’identifier en tant qu’administrateur
  2. Faire une recherche et sélection un compte
  3. Modifier les attributs de ce compte
  4. Ajouter un role déjà existant au compte
  5. Créer un role et l’ajouter au compte
  6. Ajouter un document au compte
  7. Sauver le compte
  8. Se déconnecter
  9. S’identifier en tant que le nouveau compte
  10. Se déconnecter
  11. Se reconnecter en tant qu’administrateur
  12. Remettre en état le compte

Voici un screencast de ce cas d’usage réalisé “manuellement”.

</param></param></embed>

Actions utilisateur

Ce chemin fonctionnels correspond aux étapes unitaires suivantes

  1. S’identifier en tant qu’administrateur
    • Aller sur la page d’accueil
    • Cliquer sur le lien connexion
    • Taper admin dans le champ identifiant
    • Taper admin dans le champ mot de passe
    • Cliquer sur le bouton de login
  2. Faire une recherche et sélection un compte
    • Cliquer sur le lien ‘Compte utilisateur’
    • Taper homer dans le champ identifiant
    • Sélectionner homer dans la liste de completion proposée
    • Sélectionner la ligne où homer est affichée
  3. Modifier les attributs de ce compte
    • Taper cnorris comme identifiant
    • Taper kickass comme mot de passe
    • Taper gmail@chucknorris.com comme email
    • Choisir Paris comme addresse
  4. Ajouter un role déjà existant au compte
    • Sélectionner l’onglet Droits attribués
    • Cliquer sur le bouton de recherche de droits
    • Taper admin comme nom
    • Cliquer sur rechercher
    • Sélectionner ROLE_ADMIN
  5. Créer un role et l’ajouter au compte
    • Cliquer sur le bouton de création de droits
    • Taper ROLE_GOD
    • Enregistrer le role
  6. Ajouter un document au compte
    • Sélectionner l’onglet Documents attachés
    • Cliquer sur le bouton d’ajout de documents
    • Cliquer sur le bouton d’upload
    • Sélectionner un document
  7. Sauver le compte
    • Cliquer sur le bouton sauver
  8. Se déconnecter
    • Cliquer sur le bouton deconnexion

etc.

La présentation est assez longue, mais notez que chaque élément de cette liste représente bien une action réalisée par l’utilisateur.

Résultat brut

La liste complète des actions capturées par Selenium IDE est présenté ci-dessous

Les faiblesses de ce script

En l’état la capture de Selenium IDE n’est pas utilisable pour les raisons suivantes:

  1. Le test est incomplet car il ne reflète pas toutes les actions réalisées
  2. Le test ne vérifie pas chacune des actions réalisées
  3. Le test est dépendant du temps
  4. Le test est dépendant du DOM
  5. Le test est dépendant de la langue
  6. Le test est dépendant du cookie courant
  7. Le test n’est pas refactorable
  8. Le test n’est pas composable
  9. Le test ne peut s’executer rapidement
  10. Le test n’est pas lisible par le métier
  11. Le test ne présente pas clairement les actions réalisées

Axes d’amélioration

Plusieurs axes d’amélioration s’offrent à nous.

Cookies

Nous pouvons ajouter du code pour supprimer les cookies

Refactoring

Nous pouvons refactorer le code pour extraire les actions métiers

DOM & Page factory pattern

Nous pouvons mettre en oeuvre le Page factory pattern qui permet à la fois d’apporter du typage et de résoudre en partie la dépendance forte au DOM.

Actions de vérifications

Nous pouvons ajouter des tests en plus pour vérifier le résultat des actions par exemple

Gestion du temps

Pour s’affranchir du temps de rendu des pages et des modifications du DOM, il est nécessaire d’utiliser les mécanismes de réessais de Selenium de façon judicieuse. L’utilisation de Thread.sleep() à tire larigot étant à proscrire.

Bonnes pratiques logiciel

Nous pouvons également appliquer l’ensemble des bonnes pratiques de développement pour améliorer le script original et ainsi le rendre propre et efficace.

Helpers de WebElement

L’objet WebElement est un objet de trop bas niveau, nous pouvons utiliser des helpers pour être plus efficace

La problématique liée à l’utilisation de helpers est que la liste de fonctionnalités qui prennent des WebElement est très longue.

La complétion dans votre IDE favori ne pourra pas vous aider sur les opérations possibles pour un WebElement et un contexte donné.

Il faudrait que le l’élément porte lui-même les actions qu’il peut réaliser. Ainsi un bouton ne serait pas webElement, mais un un objet de class Button où seule la méthode click() serait disponible.

Recherche de comptes utilisateurs

La recherche d’utilisateur présente à l’utilisateur les fonctionnalités suivantes:

  1. Une barre d’action contenant
    • un bouton pour créer un objet
    • un bouton pour quitter la recherche
  2. Un formulaire de recherche
    • avec des composants autocomplete
    • avec des composants d’intervalle de date
    • pouvant être réininitialisé, sauvé, chargé
  3. Un tableau
    • avec des headers cliquables pour trier par colonne
    • un composant de pagination
  4. Des lignes de résultat que l’on peut au choix supprimer, éditer, visualer et sélectionner

Ces fonctionnalités sont les mêmes sur les autres entités manipulées par l’application.

AccountSearch

Il faudrait qu’à l’image du code des composants qui produisent la page via le DOM, produire le code client qui les consomme via selenium.

Ceci dans le but d’arriver à une description des composants de la page:

Les composants Table, EntityAction, Messages, OrderBy, Autocomplete, ManyBooleans, ChooseEnum, StringRange doivent être écrits de façon indépendantes des tests.

EntityAction

Le composant EntityAction n’est qu’un aggregat de boutons

Button

Un bouton est lui-même définit comme suit

Nous pouvons désormais ajouter dans le test ce type d’action

OrderBy

Le composant OrderBy est écrit en connaissant comme le composant serveur produit le DOM côté client. Nous pouvons alors créer les méthodes isUp(), isDown(), up(), down()

Dans le test nous pouvons donc réaliser les actions et assertions suivantes:

ChooseEnum & Typage

La sélection de la civilité est interressante, voici le code

Cela permet d’avoir côté test unitaire de la completion avec le type de donnée adéquate.

Autocomplete

La suite est de componentariser les autocomplete qui est un composant plus complexe, celui-ci fait appel à de nombreuses requêtes Xpath

AccountEdit

Pour la page d’édition d’un compte nous reprenons la même recette pour arriver à ceci:

Test client

Vous l’aurez compris, une fois le code du composant produit, nous pouvons créer des tests totalement décorrolés de leur implémentations. Votre IDE pourra vous guider sur les actions possible sur chaque composant.

SeleniumTest

L’objet AccountSearch ne contient que des références de composants, leur instanciation est réalisé à la façon du Page Factory Pattern. Sauf qu’ici, leur instanciation est récursive, une class annotée @Page peut avoir des propriétés @Page. Il est à noter que les propriétés déjà créées seront également wrappées.

Test auto-documentés

Après ces pérégrinations techniques, il faut revenir au besoin client final, et savoir communiquer au métier ce que réalise le test.

Pour cela, nous avons ajouté des méthodes qui présentent visuellement les actions effecutées. L’ajout de l’annotation FollowVisually à la classe de test permet d’activer ces messages.

La notification en elle même est l’appel direct à un composant javascript déjà présent sur la page cliente.

Le highlight des composants cliqués est également présent.

Nous pouvons désormais présenter au client final le test, et pouvons améliorer les messages, itérer sur ce qui est à tester fonctionnellement, et réaliser en direct les nouveaux tests.

</param></param></embed>

Le build continu lui exécute les tests sans effets visuels, ainsi ceux-ci se déroulent aussi vite que le rendu et la vitesse de processing des pages le permettent.

Conclusion

Il est possible de pouvoir écrire des tests fonctionnels clairs, typés et rapide avec Selenium.

Pour cela, il faut investir du temps sur la création de composants qui savent intéragir avec le DOM.


© 2005-2015 Jaxio | @jaxiosoft | Mentions légales