Testen von JavaScript mit PhantomJS

Ich glaube nicht, dass ich Sie davon überzeugen muss, dass das Testen Ihres JavaScript-Codes eine gute Idee ist. Es kann jedoch manchmal langweilig sein, JavaScript-Code zu testen, für den ein DOM erforderlich ist. Das bedeutet, dass Sie Ihren Code im Browser testen müssen und das Terminal nicht verwenden können, oder? Falsch, eigentlich: Geben Sie PhantomJS ein.


Was genau ist PhantomJS? Nun, hier ist ein Klappentext von der PhantomJS-Website:

PhantomJS ist ein Headless-WebKit mit JavaScript-API.

Wie Sie wissen, ist Webkit die Layout-Engine, die von Chrome, Safari und einigen anderen Nischenbrowsern verwendet wird. PhantomJS ist also ein Browser, aber ein Headless-Browser. Dies bedeutet, dass die gerenderten Webseiten niemals tatsächlich angezeigt werden. Das mag für Sie seltsam klingen. Sie können es sich also als programmierbaren Browser für das Terminal vorstellen. Wir werden uns in einer Minute ein einfaches Beispiel anschauen, aber wir müssen zuerst PhantomJS installieren.


PhantomJS installieren

Die Installation von PhantomJS ist ziemlich einfach: Es ist nur eine einzelne Binärdatei, die Sie herunterladen und in Ihrem Terminalpfad speichern. Wählen Sie auf der PhantomJS-Downloadseite Ihr Betriebssystem aus und laden Sie das richtige Paket herunter. Verschieben Sie dann die Binärdatei aus dem heruntergeladenen Paket in ein Verzeichnis innerhalb Ihres Terminalpfads ~ / bin).

Unter Mac OS X gibt es eine einfachere Möglichkeit, PhantomJS zu installieren (und dies ist tatsächlich die von mir verwendete Methode). Verwenden Sie einfach Homebrew wie folgt:

Brüh-Update && Brüh-Installations-Phantomjs

Sie sollten jetzt PhantomJS installiert haben. Sie können Ihre Installation überprüfen, indem Sie Folgendes ausführen:

Phantomjs - Version

Ich sehe 1.7.0; Sie?


Ein kleines Beispiel

Beginnen wir mit einem kleinen Beispiel.

einfach.js
console.log ("wir können Sachen abmelden."); Funktion add (a, b) return a + b;  conslole.log ("Wir können reguläre JS auch ausführen:", add (1, 2)); phantom.exit ();

Fahren Sie fort und führen Sie diesen Code aus, indem Sie den folgenden Befehl ausgeben:

phantomjs simple.js

Sie sollten die Ausgabe von den beiden sehen console.log Zeilen in Ihrem Terminalfenster.

Sicher, das ist einfach, macht aber einen guten Punkt: PhantomJS kann JavaScript wie einen Browser ausführen. Dieses Beispiel enthält jedoch keinen PhantomJS-spezifischen Code… bis auf die letzte Zeile. Dies ist eine wichtige Zeile für jedes PhantomJS-Skript, da es das Skript beendet. Dies ist möglicherweise nicht sinnvoll, bedenken Sie jedoch, dass JavaScript nicht immer linear ausgeführt wird. Zum Beispiel möchten Sie vielleicht die Ausfahrt() Aufruf in einer Rückruffunktion.

Schauen wir uns ein komplexeres Beispiel an.


Seiten laden

Mit der PhantomJS-API können wir tatsächlich jede URL laden und aus zwei Perspektiven mit der Seite arbeiten:

  • als JavaScript auf der Seite.
  • als Benutzer, der die Seite betrachtet.

Beginnen wir mit dem Laden einer Seite. Erstellen Sie eine neue Skriptdatei, und fügen Sie den folgenden Code hinzu:

script.js
var page = required ('Webseite'). create (); page.open ('http://net.tutsplus.com', Funktion (en) console.log (s); phantom.exit (););

Wir beginnen mit dem Laden von PhantomJS ' Website Modul und Erstellen eines Webseitenobjekts. Wir rufen dann an öffnen Übergeben einer URL und einer Rückruffunktion In dieser Callback-Funktion können wir mit der eigentlichen Seite interagieren. Im obigen Beispiel protokollieren wir einfach den Status der Anforderung, die vom Parameter der Rückruffunktion bereitgestellt wird. Wenn Sie dieses Skript ausführen (mit phantomjs script.js), sollten Sie "Erfolg" im Terminal drucken lassen.

Aber machen wir das noch interessanter, indem Sie eine Seite laden und ein wenig JavaScript ausführen. Wir beginnen mit dem obigen Code, rufen aber dann an Seite bewerten:

page.open ('http://net.tutsplus.com', function () var title = page.evaluate (function () var posts = document.getElementsByClassName ("post"); posts [0] .style). backgroundColor = "# 000000"; return document.title;); page.clipRect = top: 0, links: 0, Breite: 600, Höhe: 700; page.render (title + ".png"); phantom .Ausfahrt(); );

PhantomJS ist ein Browser, aber ein Headless-Browser.

Die Funktion, an die wir übergeben werden Seite bewerten wird als JavaScript auf der geladenen Webseite ausgeführt. In diesem Fall finden wir alle Elemente mit der Post Klasse; Dann setzen wir den Hintergrund des ersten Beitrags auf Schwarz. Zum Schluss bringen wir das zurück Dokumenttitel. Dies ist eine nette Funktion, die einen Wert von unserem zurückgibt bewerten callback und ordnen es einer Variablen zu (in diesem Fall, Titel).

Dann setzen wir die clipRect auf der Seite; Das sind die Dimensionen für den Screenshot, den wir mit dem aufnehmen machen Methode. Wie Sie sehen, setzen wir das oben und links Werte, um den Startpunkt festzulegen, und wir setzen auch a Breite und Höhe. Zum Schluss rufen wir an page.render, Übergeben Sie einen Namen für die Datei (das Titel Variable). Dann beenden wir mit einem Anruf phantom.exit ().

Führen Sie dieses Skript aus und Sie sollten ein Bild haben, das ungefähr so ​​aussieht:

Sie können beide Seiten der PhantomJS-Münze hier sehen: Wir können JavaScript von der Seite aus ausführen und auch von außen auf der Seiteninstanz selbst.

Das hat Spaß gemacht, aber nicht unglaublich nützlich. Konzentrieren wir uns auf PhantomJS, wenn Sie unser DOM-bezogenes JavaScript testen.


Testen mit PhantomJS

Yeoman verwendet PhantomJS im Testverfahren und ist praktisch nahtlos.

Für eine Menge JavaScript-Code können Sie ohne DOM testen. Manchmal müssen Ihre Tests jedoch mit HTML-Elementen arbeiten. Wenn Sie wie ich sind und lieber Tests auf der Kommandozeile ausführen, kommt PhantomJS hier zum Einsatz.

Natürlich ist PhantomJS keine Testbibliothek, aber viele der anderen gängigen Testbibliotheken können auf PhantomJS ausgeführt werden. Wie Sie auf der PhantomJS-Wiki-Seite zum Headless-Testen sehen können, sind PhantomJS-Testläufer für so ziemlich jede Testbibliothek verfügbar, die Sie verwenden möchten. Schauen wir uns an, wie man PhantomJS mit Jasmine und Mocha verwendet.

Zuerst Jasmine und einen Haftungsausschluss: Es gibt derzeit keinen guten PhantomJS-Läufer für Jasmine. Wenn Sie Windows und Visual Studio verwenden, sollten Sie Chutzpah ausprobieren. Rails-Entwickler sollten Guard-Jasmin ausprobieren. Aber ansonsten ist die Unterstützung von Jasmine + PhantomJS spärlich.

Aus diesem Grund empfehle ich Ihnen, Mocha für DOM-bezogene Tests zu verwenden.

JEDOCH.

Möglicherweise haben Sie bereits ein Projekt mit Jasmine und möchten es mit PhantomJS verwenden. Ein Projekt, Phantom-Jasmin, erfordert ein wenig Arbeit, aber es sollte den Trick schaffen.

Beginnen wir mit einer Reihe von JasmineJS-Tests. Laden Sie den Code für dieses Tutorial herunter (Link oben) und überprüfen Sie die Jasmin-Starter Mappe. Sie werden sehen, dass wir eine Single haben tests.js Datei, die ein DOM-Element erstellt, einige Eigenschaften festlegt und an den Hauptteil anfügt. Anschließend führen wir einige Jasmin-Tests durch, um sicherzustellen, dass der Prozess tatsächlich richtig funktioniert hat. Hier ist der Inhalt dieser Datei:

tests.js
beschreiben ("DOM-Tests"), function () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Hi there!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); it (" ist im DOM ") function () expect (myEl) .not.toBeNull ();); it ("ist ein Kind des Körpers") function () erwartet (myEl.parentElement) .toBe (document.body);); it ("hat den richtigen Text") function () expect (myEl.innerHTML.) ) .toEqual ("Hi there!");); it ("hat den richtigen Hintergrund") function () expect (myEl.style.background) .toEqual ("rgb (204, 204, 204)"); ););

Das SpecRunner.html Datei ist ziemlich auf Lager; Der einzige Unterschied besteht darin, dass ich die Skript-Tags in den Rumpf verschoben habe, um sicherzustellen, dass das DOM vollständig geladen wird, bevor unsere Tests ausgeführt werden. Sie können die Datei in einem Browser öffnen und sehen, dass alle Tests problemlos bestanden werden.

Lassen Sie uns dieses Projekt auf PhantomJS umstellen. Klonen Sie zunächst das Phantom-Jasmin-Projekt:

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

Dieses Projekt ist nicht so organisiert, wie es sein könnte, aber es gibt zwei wichtige Teile, die Sie benötigen:

  • der PhantomJS-Läufer (wodurch Jasmine ein PhantomJS-DOM verwendet).
  • der Jasmine Console Reporter (der die Konsolenausgabe liefert).

Diese beiden Dateien befinden sich im lib Mappe; kopiere sie in Jasmin-Starter / lib. Wir müssen jetzt unsere öffnen SpecRunner.html Datei und passen Sie die

Beachten Sie, dass wir zwei Reporter für unsere Tests haben: einen HTML-Reporter und einen Konsolenreporter. Das heisst SpecRunner.html und seine Tests können sowohl im Browser als auch in der Konsole ausgeführt werden. Das ist praktisch. Leider müssen wir das haben console_reporter Variable, weil sie in der CoffeeScript-Datei verwendet wird, die gerade ausgeführt wird.

Wie gehen wir also vor, um diese Tests tatsächlich auf der Konsole auszuführen? Vorausgesetzt du bist in der Jasmin-Starter Ordner auf dem Terminal, hier der Befehl:

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

Wir führen die Führen Sie \ _jasmine \ _test.coffee aus Skript mit PhantomJS und übergeben unser SpecRunner.html Datei als Parameter. Sie sollten so etwas sehen:

Wenn ein Test fehlschlägt, wird Folgendes angezeigt:

Wenn Sie planen, dies häufig zu verwenden, ist es möglicherweise eine gute Idee, umzuziehen Führen Sie \ _jasmine \ _test.coffee aus zu einem anderen Ort (wie ~ / bin / run \ _jasmine \ _test.coffee) und erstellen Sie einen Terminal-Alias ​​für den gesamten Befehl. So machen Sie das in einer Bash-Shell:

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

Wirf das einfach in deine .bashrc oder .bash_profile Datei. Jetzt können Sie einfach ausführen:

Phantom-Jasmin SpecRunner.html

Jetzt funktionieren Ihre Jasmin-Tests auf PhantomJS problemlos auf dem Terminal. Sie können den endgültigen Code in sehen Jasmin-Gesamt Ordner im Download.


PhantomJS und Mocha

Zum Glück ist es viel einfacher, Mocha und PhantomJS mit Mocha-Phantomjs zu integrieren. Es ist sehr einfach zu installieren, wenn Sie NPM installiert haben (was Sie sollten):

npm install -g Mocha-Phantomjs

Dieser Befehl installiert eine Mocha-Phantomjs binär, das wir verwenden, um unsere Tests auszuführen.

In einem früheren Tutorial habe ich Ihnen gezeigt, wie Sie Mocha im Terminal verwenden. Sie werden jedoch anders vorgehen, wenn Sie DOM-Code testen. Wie bei Jasmine beginnen wir mit einem HTML-Testreporter, der im Browser ausgeführt werden kann. Das Schöne daran ist, dass wir dieselbe Datei auf dem Terminal ausführen können, um mit PhantomJS Ergebnisse der Konsolentests zu erhalten. So wie wir es mit Jasmine konnten.

Lassen Sie uns also ein einfaches Projekt erstellen. Erstellen Sie ein Projektverzeichnis und verschieben Sie es in dieses Verzeichnis. Wir fangen mit einem an package.json Datei:

"name": "project", "version": "0.0.1", "devDependencies": "mocha": "*", "chai": "*"

Mocha ist das Test-Framework, und wir verwenden Chai als Assertionsbibliothek. Wir installieren diese, indem wir NPM ausführen.

Wir rufen unsere Testdatei an test / tests.js, und hier sind seine Tests:

beschreiben ("DOM-Tests"), function () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Hi there!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); it (" ist im DOM ") function () expect (myEl) .to.not.equal (null); ); it ("ist ein Kind des Körpers") function () erwartet (myEl.parentElement) .to.equal (document.body);); it ("hat den richtigen Text", function ()  erwarten (myEl.innerHTML) .to.equal ("Hi there!");); es ("hat den richtigen Hintergrund") function () erwartet (myEl.style.background) .to.equal ("rgb ( 204, 204, 204) ");););

Sie sind den Jasmin-Tests sehr ähnlich, aber die Chai-Assertions-Syntax ist etwas anders (kopieren Sie also nicht nur Ihre Jasmin-Tests)..

Das letzte Puzzleteil ist das TestRunner.html Datei:

   Tests     

Hier gibt es mehrere wichtige Faktoren. Beachten Sie zunächst, dass dies vollständig genug ist, um in einem Browser ausgeführt zu werden. Wir haben CSS und JavaScript aus den Knotenmodulen, die wir installiert haben. Beachten Sie dann das Inline-Skript-Tag. Dies bestimmt, ob PhantomJS geladen ist, und führt in diesem Fall die PhantomJS-Funktionalität aus. Ansonsten bleibt es mit roher Mocha-Funktionalität erhalten. Sie können dies im Browser ausprobieren und sehen, dass es funktioniert.

Um es in der Konsole auszuführen, führen Sie einfach Folgendes aus:

Mocha-Phantomjs TestRunner.html

Voila! Jetzt laufen die Tests in der Konsole, und das alles dank PhantomJS.


PhantomJS und Yeoman

Ich wette, Sie wussten nicht, dass der beliebte Yeoman PhantomJS in seinem Testverfahren verwendet, und es ist scheinbar unbemerkt. Schauen wir uns ein kurzes Beispiel an. Ich gehe davon aus, dass Sie Yeoman eingerichtet haben.

Erstellen Sie ein neues Projektverzeichnis, und führen Sie es aus yeoman init darin, und antworten Sie mit "Nein" zu allen Optionen. Öffne das test / index.html Datei, und Sie finden ein Skript-Tag am unteren Rand mit einem Kommentar, der Sie dazu auffordert, es durch Ihre eigenen Spezifikationen zu ersetzen. Ignorieren Sie diesen guten Rat vollständig und legen Sie ihn in den es Block:

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

Nun laufe Yeoman-Test, und Sie werden sehen, dass der Test gut läuft. Jetzt offen test / index.html Datei im Browser. Es klappt! Perfekt!

Natürlich können Sie mit Yeoman noch viel mehr tun. Schauen Sie sich die Dokumentation an, um mehr zu erfahren.


Fazit

Verwenden Sie die Bibliotheken, die PhantomJS erweitern, um das Testen zu vereinfachen.

Wenn Sie PhantomJS alleine verwenden, gibt es keinen Grund, mehr über PhantomJS selbst zu erfahren. Sie können nur wissen, dass es vorhanden ist, und die Bibliotheken verwenden, die PhantomJS erweitern, um das Testen zu vereinfachen.

Ich hoffe, dieses Tutorial hat Sie ermutigt, sich mit PhantomJS zu beschäftigen. Ich empfehle, mit den Beispieldateien und der Dokumentation von PhantomJS zu beginnen. Sie öffnen wirklich Ihre Augen für das, was Sie mit PhantomJS tun können - von der Seitenautomatisierung bis zum Netzwerk-Sniffing.

So, können Denken Sie an ein Projekt, das PhantomJS verbessern würde? Lass uns in den Kommentaren darüber erfahren!