Tester JavaScript avec PhantomJS

Je ne pense pas avoir besoin de vous convaincre que tester votre code JavaScript est une bonne idée. Cependant, il peut parfois s'avérer fastidieux de tester du code JavaScript nécessitant un DOM. Cela signifie que vous devez tester votre code dans le navigateur et que vous ne pouvez pas utiliser le terminal, n'est-ce pas? Faux, effectivement: entrez PhantomJS.


Qu'est-ce que PhantomJS? Eh bien, voici un texte de présentation du site Web de PhantomJS:

PhantomJS est un kit Web sans tête avec API JavaScript.

Comme vous le savez, Webkit est le moteur de disposition utilisé par Chrome, Safari et quelques autres navigateurs de niche. Donc, PhantomJS est un navigateur, mais un navigateur sans tête. Cela signifie que les pages Web rendues ne sont jamais réellement affichées. Cela peut vous paraître étrange. vous pouvez donc le considérer comme un navigateur programmable pour le terminal. Nous allons regarder un exemple simple dans une minute, mais nous devons d’abord installer PhantomJS.


Installer PhantomJS

L'installation de PhantomJS est en fait assez simple: il ne s'agit que d'un simple binaire que vous téléchargez et collez dans le chemin du terminal. Sur la page de téléchargement de PhantomJS, choisissez votre système d'exploitation et téléchargez le package approprié. Déplacez ensuite le fichier binaire du paquet téléchargé vers un répertoire situé dans le chemin de votre terminal (j'aime mettre ce genre de chose dans ~ / bin).

Si vous utilisez Mac OS X, il existe un moyen plus simple d’installer PhantomJS (c’est la méthode que j’ai utilisée). Il suffit d'utiliser Homebrew, comme ceci:

mise à jour de brew && brew installer phantomjs

Vous devriez maintenant avoir installé PhantomJS. Vous pouvez vérifier votre installation en lançant ceci:

phantomjs --version

Je vois 1.7.0; vous?


Un petit exemple

Commençons par un petit exemple.

simple.js
console.log ("nous pouvons déconnecter des choses."); fonction add (a, b) retour a + b;  conslole.log ("Nous pouvons aussi exécuter JS classique:", add (1, 2)); phantom.exit ();

Continuez et exécutez ce code en exécutant la commande suivante:

phantomjs simple.js

Vous devriez voir la sortie des deux console.log lignes dans la fenêtre de votre terminal.

Bien sûr, c’est simple, mais c’est un bon point: PhantomJS peut exécuter JavaScript comme un navigateur. Cependant, cet exemple n'a pas de code spécifique à PhantomJS… eh bien, mis à part la dernière ligne. C'est une ligne importante pour chaque script PhantomJS car elle quitte le script. Cela n’a peut-être pas de sens ici, mais souvenez-vous que JavaScript ne s’exécute pas toujours de manière linéaire. Par exemple, vous voudrez peut-être mettre le sortie() appeler une fonction de rappel.

Regardons un exemple plus complexe.


Chargement des pages

À l'aide de l'API PhantomJS, nous pouvons charger n'importe quelle URL et utiliser la page sous deux angles:

  • en JavaScript sur la page.
  • en tant qu'utilisateur regardant la page.

Commençons par choisir de charger une page. Créez un nouveau fichier de script et ajoutez le code suivant:

script.js
var page = require ('page Web'). create (); page.open ('http://net.tutsplus.com', fonction (s) console.log (s); phantom.exit (););

Nous commençons par charger PhantomJS ' page Web module et création d'un objet de page Web. Nous appelons ensuite le ouvrir méthode, en lui passant une URL et une fonction de rappel; c'est à l'intérieur de cette fonction de rappel que nous pouvons interagir avec la page réelle. Dans l'exemple ci-dessus, nous enregistrons simplement l'état de la demande, fourni par le paramètre de la fonction de rappel. Si vous exécutez ce script (avec phantomjs script.js), vous devriez avoir "succès" imprimé dans le terminal.

Mais rendons cela plus intéressant en chargeant une page et en exécutant du JavaScript dessus. Nous commençons avec le code ci-dessus, mais nous appelons ensuite page.évaluer:

page.open ('http://net.tutsplus.com', function () var title = page.evaluate (function () var posts = document.getElementsByClassName ("post"); posts [0] .style. backgroundColor = "# 000000"; retourne document.title;); page.clipRect = haut: 0, gauche: 0, largeur: 600, hauteur: 700; page.render (titre + ".png"); fantôme .sortie(); );

PhantomJS est un navigateur, mais un navigateur sans tête.

La fonction à laquelle nous passons page.évaluer s'exécute en tant que JavaScript sur la page Web chargée. Dans ce cas, on trouve tous les éléments avec le poster classe; ensuite, nous définissons l’arrière-plan du premier message en noir. Enfin, nous retournons le titre du document. Ceci est une fonctionnalité intéressante, renvoyant une valeur de notre évaluer rappel et l'attribuer à une variable (dans ce cas, Titre).

Ensuite, nous définissons le clipRect sur la page; ce sont les dimensions de la capture d'écran que nous prenons avec le rendre méthode. Comme vous pouvez le constater, nous définissons la Haut et la gauche valeurs pour définir le point de départ, et nous définissons également un largeur et la taille. Enfin, nous appelons page.render, en lui donnant un nom pour le fichier (le Titre variable). Ensuite, nous finissons par appeler phantom.exit ().

Allez-y et exécutez ce script, et vous devriez avoir une image qui ressemble à ceci:

Vous pouvez voir les deux côtés de la pièce PhantomJS ici: nous pouvons exécuter JavaScript à partir de l'intérieur de la page, et également exécuter de l'extérieur, sur l'instance de page elle-même..

Cela a été amusant, mais pas incroyablement utile. Concentrons-nous sur l'utilisation de PhantomJS lors du test de notre JavaScript lié à DOM.


Test avec PhantomJS

Yeoman utilise PhantomJS dans sa procédure de test, et il est pratiquement transparent.

Pour beaucoup de code JavaScript, vous pouvez tester sans recourir à un DOM, mais vos tests doivent parfois fonctionner avec des éléments HTML. Si vous êtes comme moi et préférez exécuter des tests en ligne de commande, c'est ici que PhantomJS entre en jeu..

Bien entendu, PhantomJS n’est pas une bibliothèque de test, mais de nombreuses autres bibliothèques de test populaires peuvent s’exécuter sur PhantomJS. Comme vous pouvez le voir sur la page Wiki de PhantomJS sur les tests sans en-tête, les coureurs de tests PhantomJS sont disponibles pour à peu près toutes les bibliothèques de tests que vous souhaitez utiliser. Regardons comment utiliser PhantomJS avec Jasmine et Mocha.

Tout d’abord, Jasmine et un avertissement: Jasmine n’est pas un bon coureur pour le moment. Si vous utilisez Windows et Visual Studio, vous devriez jeter un œil à Chutzpah et les développeurs Rails devraient essayer guard-jasmine. Mais à part cela, le support de Jasmine + PhantomJS est rare.

Pour cette raison, je vous recommande d'utiliser Mocha pour les tests liés à DOM..

TOUTEFOIS.

Il est possible que vous ayez déjà un projet utilisant Jasmine et que vous souhaitiez l'utiliser avec PhantomJS. Un projet, phantom-jasmine, demande un peu de travail, mais il devrait faire l'affaire.

Commençons par un ensemble de tests JasmineJS. Téléchargez le code de ce didacticiel (lien en haut) et consultez le jasmin-entrée dossier. Vous verrez que nous avons un seul tests.js fichier qui crée un élément DOM, définit quelques propriétés et l’ajoute au corps. Ensuite, nous effectuons quelques tests Jasmine pour nous assurer que le processus a bien fonctionné correctement. Voici le contenu de ce fichier:

tests.js
describe ("Tests DOM", function () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Bonjour!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); it (" est dans le DOM ", function () expect (myEl) .not.toBeNull ();); it ("est un enfant du corps", function () expect (myEl.parentElement) .toBe (document.body);); it ("a le bon texte", function () expect (myEl.innerHTML ) .toEqual ("Bonjour!");); elle ("a le bon fond", function () expect (myEl.style.background) .toEqual ("rgb (204, 204, 204)"); ););

le SpecRunner.html le fichier est assez stock; La seule différence est que j'ai déplacé les balises de script dans le corps pour assurer le chargement complet du DOM avant l'exécution de nos tests. Vous pouvez ouvrir le fichier dans un navigateur et constater que tous les tests sont satisfaisants..

Passons ce projet à PhantomJS. Tout d’abord, clonez le projet phantom-jasmine:

git clone git: //github.com/jcarver989/phantom-jasmine.git

Ce projet n’est pas aussi organisé qu’il pourrait être, mais vous en avez besoin de deux éléments importants:

  • le coureur PhantomJS (ce qui oblige Jasmine à utiliser un DOM PhantomJS).
  • le rapporteur de la console Jasmine (qui donne la sortie de la console).

Ces deux fichiers résident dans le lib dossier; les copier dans jasmin-starter / lib. Nous devons maintenant ouvrir notre SpecRunner.html déposer et ajuster le

Notez que nous avons deux journalistes pour nos tests: un journaliste HTML et un journaliste sur console. Ça signifie SpecRunner.html et ses tests peuvent s’exécuter dans le navigateur et la console. C'est pratique. Malheureusement, nous avons besoin de cela console_reporter variable parce qu'il est utilisé à l'intérieur du fichier CoffeeScript que nous sommes sur le point d'exécuter.

Alors, comment pouvons-nous exécuter ces tests sur la console? En supposant que vous êtes dans le jasmin-entrée dossier sur le terminal, voici la commande:

phantomjs lib / run \ _jasmine \ _test.coffee ./SpecRunner.html

Nous courons le lancer \ _jasmine \ _test.coffee script avec PhantomJS et en passant notre SpecRunner.html fichier en tant que paramètre. Vous devriez voir quelque chose comme ça:

Bien sûr, si un test échoue, vous verrez quelque chose comme ce qui suit:

Si vous envisagez d’utiliser cela souvent, il peut être judicieux de déplacer lancer \ _jasmine \ _test.coffee vers un autre endroit (comme ~ / bin / run \ _jasmine \ _test.coffee) et créez un alias de terminal pour toute la commande. Voici comment procéder dans un shell Bash:

alias phantom-jasmine = "phantomjs /path/to/run\_jasmine\_test.coffee"

Il suffit de jeter cela dans votre .bashrc ou .bash_profile fichier. Maintenant, vous pouvez simplement lancer:

phantom-jasmine SpecRunner.html

Maintenant, vos tests Jasmine fonctionnent parfaitement sur le terminal via PhantomJS. Vous pouvez voir le code final dans le jasmin total dossier dans le téléchargement.


PhantomJS et Moka

Heureusement, il est beaucoup plus facile d'intégrer Mocha et PhantomJS avec mocha-phantomjs. Il est très facile à installer si vous avez NPM installé (ce que vous devriez):

npm installer -g mocha-phantomjs

Cette commande installe un moka-phantomjs binaire que nous utiliserons pour exécuter nos tests.

Dans un précédent tutoriel, je vous ai montré comment utiliser Mocha dans le terminal, mais vous ferez les choses différemment lorsque vous l'utiliserez pour tester le code DOM. Comme pour Jasmine, nous commencerons par un reporter de test HTML pouvant s'exécuter dans le navigateur. La beauté de ceci est que nous pourrons exécuter ce même fichier sur le terminal pour les résultats des tests de console avec PhantomJS; comme nous le pouvions avec Jasmine.

Construisons donc un projet simple. Créez un répertoire de projet et déplacez-vous dans celui-ci. Nous allons commencer avec un package.json fichier:

"nom": "projet", "version": "0.0.1", "devDependencies": "mocha": "*", "chai": "*"

Mocha est le framework de test, et nous utiliserons Chai comme bibliothèque d'assertions. Nous les installons en exécutant NPM.

Nous appellerons notre fichier de test test / tests.js, et voici ses tests:

describe ("Tests DOM", function () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Bonjour!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); it (" est dans le DOM ", function () expect (myEl) .to.not.equal (null); ); it ("est un enfant du corps", function () expect (myEl.parentElement) .to.equal (document.body);); it ("a le texte correct", function ()  expect (myEl.innerHTML) .to.equal ("Bonjour!");); it ("a le bon fond", function () expect (myEl.style.background) .to.equal ("rgb ( 204, 204, 204) ");););

Ils sont très similaires aux tests Jasmine, mais la syntaxe d'assertion Chai est un peu différente (donc, ne copiez pas simplement vos tests Jasmine)..

La dernière pièce du puzzle est la TestRunner.html fichier:

   Des tests     

Il y a plusieurs facteurs importants ici. Tout d’abord, notez que cela est suffisamment complet pour être exécuté dans un navigateur; nous avons les CSS et JavaScript des modules de nœuds que nous avons installés. Ensuite, notez la balise de script en ligne. Cela détermine si PhantomJS est chargé et, le cas échéant, exécute la fonctionnalité PhantomJS. Sinon, il reste avec la fonctionnalité Moka brut. Vous pouvez essayer ceci dans le navigateur et le voir fonctionner.

Pour l'exécuter dans la console, lancez simplement ceci:

mocha-phantomjs TestRunner.html

Voila! Maintenant, vos tests sont exécutés dans la console, et tout cela grâce à PhantomJS.


PhantomJS et Yeoman

Je parie que vous ne saviez pas que le populaire Yeoman utilise PhantomJS dans sa procédure de test, et qu’il est pratiquement silencieux. Regardons un exemple rapide. Je suppose que vous avez Yeoman tous mis en place.

Créez un nouveau répertoire de projet, exécutez yeoman init à l'intérieur, et répondez «Non» à toutes les options. Ouvrez le test / index.html fichier, et vous trouverez une balise de script vers le bas avec un commentaire vous invitant à le remplacer par vos propres spécifications. Ignorer complètement ce bon conseil et le mettre à l’intérieur du il bloc:

var el = document.createElement ("div"); expect (el.tagName) .to.equal ("DIV");

Maintenant, lancez test yeoman, et vous verrez que le test fonctionne bien. Ouvert test / index.html fichier dans le navigateur. Ça marche! Parfait!

Bien sûr, il y a beaucoup plus que vous pouvez faire avec Yeoman, alors consultez la documentation pour plus d'informations..


Conclusion

Utilisez les bibliothèques qui étendent PhantomJS pour simplifier vos tests.

Si vous utilisez PhantomJS seul, il n’ya aucune raison de vous renseigner sur PhantomJS lui-même; vous pouvez simplement savoir qu'il existe et utiliser les bibliothèques qui étendent PhantomJS pour simplifier vos tests.

J'espère que ce tutoriel vous a incité à examiner PhantomJS. Je recommande de commencer avec les exemples de fichiers et la documentation proposés par PhantomJS; ils vous ouvriront vraiment les yeux sur ce que vous pouvez faire avec PhantomJS - de l’automatisation de la page au sniffing de réseau.

Alors, pouvez vous pensez à un projet que PhantomJS pourrait améliorer? Écoutons-le dans les commentaires!