Pages

vendredi 8 mai 2015

Tests d'intégration dans une application Angular via Protactor


Je vais revenir sur la série d'articles que j'ai faite sur les tests en Javascript et la compléter. Pour rappel j'ai déjà aborder

Les tests d'intégration

Il manque dans cette liste les tests d'intégration. Quand nous développons une application, il est important de compléter les tests unitaires par des tests d'intégration aussi appelés tests end-to-end. Ces tests permettent de vérifier le comportement de votre application de bout en bout comme un humain le ferait. Ils sont plus longs que les tests unitaires et ne permettent pas de tester les cas au limites. Vous devez concentrer vos efforts sur les stories les plus critiques ou les plus importantes de votre application.

Quand on parle de tests end-to-end vous devez normalement vérifier l'application côté présentation et côté serveur. Ce scénario peut être difficile.
  • le serveur doit être installé au moment de l'exécution des tests 
  • si vous avez une base de données, il faut qu'elle soit chargée et il faut que les tests puissent s'enchaîner dans n'importe quel ordre (une suppression ou un ajout de ne doit pas impacter un test de sélection…) 
  • … 
Pour vous simplifier la vie vous pouvez simuler le comportement de la partie serveur et vous concentrez sur les tests de l'interface. Personnellement je préfère cette solution car elle permet d'avoir des tests plus rapides et un processus de build plus simple.

Au niveau des tests d'intégration pour une application web, plusieurs outils peuvent être utilisés comme CasperJS ou Selenium. Mais comme mon intérêt Javascript du moment est le framework Angular je vais plutôt m'attarder sur Protractor, l'outil développé et préconisé par l'équipe Angular. Comme vous allez le voir Selenium n'est pas très loin...



Protractor

Protractor est une application qui permet d’exécuter vos tests dans Node.js plutôt que dans un navigateur internet, comme Karma le propose. Protractor communique ensuite avec le navigateur par l’intermédiaire de Selenium.

Selenium est un framework permettant de piloter un navigateur Internet. Il propose un serveur, des drivers pour accéder aux différents navigateurs (les webdrivers) et une API pour piloter des actions sur une interface web, et vérifier les réponses.

Protractor se propose de faire la glue entre votre projet Angular et Selenium. Il propose sa propre API Javascript.



Pour écrire vos tests e2e, vous pouvez utiliser les frameworks Jasmine, Mocha ou Cucumber.

Le principe est assez simple vous devez dans un fichier de tests écrit en Javascript
  1. décrire les différentes actions que Protractor devra exécuter dans le navigateur. En gros on décrit les actions de l'utilisateur final. On lui demande de cliquer sur un lien, remplir une valeur dans un formulaire... 
  2. vérifier le résultat de ces actions : état de l’application, texte à l’écran, URL…. 

Comment installer Protractor ?

Utilisez le gestionnaire de paquet Node.js pour installer Protractor au niveau de votre projet  
npm install protractor

Vous pouvez ensuite installer les drivers web qui permettront à Protractor de communiquer avec les navigateurs.
./node_modules/protractor/bin/webdriver-manager update


Vous pouvez bien évidemment paramétrer tout ceci au niveau de votre configuration npm et le fichier package.json. En personnalisant le script « test » l'installation pourra se faire d'elle même quand vous lancez la tâche
npm test

{
  "name": "javamind-karma",
  "version": "0.0.1",
  "description": "Javamind tests en Javascript",
  "main": "index.js",
  "dependencies": {},
  "devDependencies": {
    "protractor": "^1.6.1",
    "jasmine-reporters": "~1.0.1"
  },
  "author": "Guillaume EHRET",
  "scripts": {
    "test": "npm install && ./node_modules/protractor/bin/webdriver-manager update && ./node_modules/protractor/bin/protractor protractor.conf.js"
  }
}

Nous allons lancer Selenium via la commande
./node_modules/protractor/bin/webdriver-manager start

Dans les exemples que je vais donner un peu plus loin nous lancerons le serveur manuellement. Dans la vraie vie nous aurons lutôt tendance à utiliser les modules Grunt ou Gulp qui se chargent de charger votre application et le serveur Selenium avant l’exécution des tests.

Un premier exemple ?

Nous allons écrire un premier fichier exemple qui vérifiera la balise title de mon site web http://dev-mind.fr/.

describe('Test homepage (index.html)', function() {
    it('should have a title', function() {
        browser.get('http://dev-mind.fr/');
        expect(browser.getTitle()).toEqual('DevIsMyMind');
    });
});

L’objet browser est un objet fournit par l’API Protractor . Il permet de lancer des actions

  • get pour charger une URL
  • getTitle pour récupérer le titre de la page
La documentation décrit tous les objets et fonctions disponibles mais elle est assez succincte et apparaît comme un défaut du projet. Pour des exemples concrets vous pouvez vous référer aux exemples donnés sur le site Angular dans le guide du développeur, la description de l'API ou le tutoriel.


Paramétrer Protractor

Nos fichiers sont prêts mais nous devons paramétrer Protractor pour qu’il

  • soit capable de trouver ces fichiers de tests
  • puisse interagir avec le serveur Selenium
  • connaissent les navigateurs à utiliser
  • ...

Nous allons donc créer un fichier protractor.conf.js. Nous prenons un exemple minimal mais vous pouvez récupérer le fichier de référence à l’adresse suivante.

exports.config = {
    // The address of a running selenium server.
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['./test/e2e/*.spec.js'],
    multiCapabilities: [ {browserName: 'chrome'}]
};

Vous pouvez lancer les tests via la commande
./node_modules/protractor/bin/protractor protractor.conf.js

Attention avant de le faire vous devez avoir lancé le serveur Selenium (voir plus haut), et si tout va bien vous aurez par exemple la sortie suivante



Aller un peu plus loin

Pour le moment le test écrit est un peu simple. Nous allons voir comment le modifier. Sur mon site web je propose par exemple une formation Angular et nous allons maintenant écrire le test qui vérifie que le document PDF décrivant le programme se lance bien.

describe('Test homepage (index.html)', function () {
  it('should have a link to open training ', function () {
    browser.get('http://dev-mind.fr/');
    var link = element.all(by.css('.myformations a')).first();

    //My link has an image
    expect(link.getInnerHtml()).toMatch('angularjs.png');
    //The URL
    expect(link.getAttribute("href")).toBe('http://dev-mind.fr/raw/FormationAngular.pdf');
  });
});

J'ai utilisé la fonction element qui permet de parcourir le DOM et rechercher des nœuds de l'arbre HTML. Cette fonction admet en argument un localisateur (locator), la fonction by.

Une fois que j'ai identifié le nœud qui m'intéressait dans le DOM, je peux vérifier le contenu d'une propriété, le contenu de la balise….

Nous pouvons également envoyer des actions. Si je voulais cliquer sur le lien je pourrais écrire
link.click() ;


Et ...
Je vais arrêter ici pour aujourd’hui la description de Protactor. La prochaine fois j'essayerai d'aller un peu plus loin en montrant plus d'exemples sur comment trouver des nœuds, lancer des actions, debugguer des tests…

Aucun commentaire:

Enregistrer un commentaire

Remarque : Seul un membre de ce blog est autorisé à enregistrer un commentaire.