Seit einigen Monaten fragen sich Entwickler, was für ihre Akzeptanztests in einem neuen Projekt verwendet werden soll. Das CasperJS Team hat lange keine Updates veröffentlicht. Protractor hat die Angular-Community nie wirklich überzeugt, daher scheint es keine solide Lösung zu sein. Glücklicherweise kam die JS-Community zur Rettung! Hier kommt Nachtwache (Nein, es hat nichts mit Game Of Thrones zu tun …)
(Englische Version ist hier: https://www.ux-republic.com/introduction-a-nightwatch-tests-dacceptance-ultra-rapides/)
Präsentation

Sehen wir uns zunächst eine Illustration an, die ziemlich gut zusammenfasst, wie Nightwatch funktioniert und wie es mit Selenium und dem Browser selbst interagiert.

Nightwatch unterscheidet sich in vielerlei Hinsicht von seiner Konstante:
- Wie bereits erwähnt, ist seine Syntax immer noch ziemlich edel
- Es ist einfach zu erweitern (wir werden übrigens später sehen, wie das geht)
- Es enthält die Seitenobjektmuster aus dem Kasten heraus
- Mit Selenium unter der Haube sollten Sie das Ökosystem dieser Plattform genießen. Ich denke an Sass-Tools wie BrowserStack or Sauce Labors und all Webtreiber zum Beispiel. Darüber hinaus können sie über alle Browser ausgeführt werden.
- Eines der besten, das Killer-Feature: Nightwatch kann Parallelisieren Sie Ihre Testsuite!
Nun, zeig mir den Code!
Erste Schritte
Bevor wir beginnen, sehen wir einen Baum Boilerplate-Projekt erstellt für diesen speziellen Artikel:
├── Nachtwache.json
├── nightwatch.globals.js
├── jetzt
│ ├── Berichte
│ ├── Protokolle
│ └── Prüfungen
└── Paket.json
Wenn Sie die vollständige Lösung direkt möchten, sollten Sie dieses Repository einfach klonen.
Wie üblich beginnen wir mit der Installation der erforderlichen Pakete (im Stammverzeichnis des Projekts):
npm install nightwatch selenium-server-standalone-jar chromedriver –save-dev
Die erste Abhängigkeit ist die einzige, die zwingend erforderlich ist. Um jedoch Zeit bei der Konfiguration zu sparen, empfehlen wir die Installation eines Pakets, das den Selenium-Server (eine einfache JAR-Datei ) enthält, und eines weiteren, das den ChromeDriver enthält.
Der nächste Schritt besteht darin, die Nightwatch-Konfigurationsdatei zu erstellen. Nennen wir sie nightwatch.json . Die Beispieldatei sieht wie folgt aus (die einzelnen Felder werden später erläutert):
{
"src_folders" : ["nw/tests"],
"output_folder" : "nw/reports",
"globals_path" : "nightwatch.globals.js",
"test_workers": {
"enabled": true,
"workers": "auto"
},
"selenium" : {
"start_process" : true,
"server_path" : "./node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-2.50.1.jar",
"log_path" : "nw/logs",
"host" : "127.0.0.1",
"port" : 4444,
"cli_args" : {
"webdriver.chrome.driver" : "./node_modules/chromedriver/bin/chromedriver",
"webdriver.ie.driver" : ""
}
},
"test_settings" : {
"default" : {
"launch_url" : "http://google.com",
"selenium_port" : 4444,
"selenium_host" : "localhost",
"silent": true,
"screenshots" : {
"enabled" : true,
"path" : ""
},
"desiredCapabilities": {
"browserName": "chrome",
"javascriptEnabled": true,
"acceptSslCerts": true
}
},
"french" : {
"launch_url" : "http://google.fr",
"desiredCapabilities": {
"browserName": "firefox",
"javascriptEnabled": true,
"acceptSslCerts": true
}
}
}
}
- src_folders: Verzeichnis mit den Testsuiten
- Ausgabeordner: Verzeichnis mit den Testberichten
- test_worders: Definieren Sie, ob wir Testsuiten parallel ausführen möchten oder nicht. Hier aktivieren wir die Parallelisierung (aktivieren: wahr) und wir definieren automatisch die Anzahl der parallelen Instanzen in Bezug auf CPU/Kern
- globals_path : Datei, in der wir die globalen Parameter der Testsuiten einrichten
- selenium: Dieser Teil definiert die allgemeine Konfiguration, um Nightwatch mit Selenium zu verbinden. Es spielt in diesem Artikel keine Rolle, aber bitte beachten Sie, dass wir hier den Pfad zum Selenium-Server und zum Chrome-Treiber definieren.
- test_einstellungen : Dieser Teil ist wahrscheinlich der interessanteste, da er Ihnen erlaubt, Ihre Testumgebungen zu definieren. In diesem Beispiel definieren wir die Standardumgebungsparameter und die französischen Umgebungsparameter. Beachten Sie, dass die anderen Umgebungen die Standardkonfiguration erben. Deshalb müssen wir nur die Ziel-URL (launch_url) und den Browser (desiredCapabilities) überschreiben.
Die Auswahl des `desiredCapabilities`-Blocks mag zunächst etwas ungewöhnlich erscheinen, da er lediglich den zu verwendenden Browser festlegt. Dieses Format ist jedoch eine Übernahme aus der Selenium-Konfiguration und ermöglicht es Benutzern, zahlreiche Parameter im gewählten Browser zu konfigurieren. Weitere Informationen finden Sie in der offiziellen Dokumentation.
Erster Test
Es ist Zeit für Ihren ersten Test. Erstellen Sie die Datei nw/tests/researchOnGoogle.test.js. Sie sollte folgenden Code enthalten:
module.exports = {
'Search on google': (browser) => {
browser
.init()
.waitForElementVisible('body', 1000)
.setValue('input[type=text]', 'nightwatch')
.waitForElementVisible('button[name=btnG]', 1000)
.click('button[name=btnG]')
.pause(1000)
.assert.containsText('#main', 'Night Watch')
.end()
},
after: (browser) => {
browser.end()
}
};
Diese Datei beschreibt eine Testsuite mit dem Test „Google-Suche“. Der Test beginnt mit einer Initialisierung , die die Webseite aufruft. Anschließend wird mit `waitForElement` gewartet, bis ein Element sichtbar ist. Mit `setValue` wird ein Wert in das Suchfeld eingetragen . Mit `click` wird auf die Suchschaltfläche geklickt (nachdem deren Vorhandensein überprüft wurde). Danach wird mit ` pause` eine Sekunde gewartet . Abschließend ruft Nightwatch am Ende des Tests automatisch die Funktion `after` auf, gefolgt vom Aufruf der ` end` -Methode.
Der Aufruf der `end` -Methode ist sehr wichtig, da sie den Browser schließt, der zum Ausführen des Tests verwendet wurde. Ich empfehle Ihnen, diese Methode am Ende jedes Tests aufzurufen, gefolgt von `after`.
Lass uns jetzt laufen:
node_modules/nightwatch/bin/nightwatch -c nightwatch.json

Das Ergebnis sollte so aussehen. Ein Chrome sollte zur gleichen Zeit im Hintergrund laufen.
Möchten Sie den Test jetzt mit der 'französischen' Umgebung durchführen? Zu einfach… Lauf einfach:
node_modules/nightwatch/bin/nightwatch -c nightwatch.json –env englisch
Keine sichtbare Änderung in der Konsole, allerdings wird diesmal ein Firefox statt Chrome ausgeführt und es geht auf „http://google.fr“ statt „http://google.com“.
Die „Globals“, um es einfach zu machen
Die Globals-Datei ist nützlich, um Ihre Tests zu vereinfachen, indem einige Globals-Parameter definiert werden. Zum Beispiel müssen wir jedes Mal die Timeout-Dauer definieren, um ein HTML-Element zu finden. Es wäre wunderbar, diese Timeout-Dauer einmal global definieren zu können. Es ist die Art von Möglichkeit, die diese Datei bietet. Sie können auch definieren Haken für verschiedene Momente dynamische Umgebungsvariablen (die Nightwatch-Konfigurationsdatei ist eine deklarative JSON-Datei, sodass Sie keine dynamischen Variablen definieren können)
Die Konfigurationsdatei sollte wie folgt aussehen (Kommentare sollten definitiv helfen):
module.exports = {
'default': { // 'default' environnement parameters
searchTerm : 'nightwatch',
movieName : 'Night Watch'
},
'french': { // 'french' environnement parameters
searchTerm : 'dikkenek',
movieName : 'dikkenek'
},
// Abord all on test fail
abortOnAssertionFailure: true,
// Duration between two checks
waitForConditionPollInterval: 300,
// Timeout duration
waitForConditionTimeout: 1000,
/*
* Define if the test failed when many HTML elements are found when
* we expect only one
*/
throwOnMultipleElementsReturned: false,
// Before/After Hooks of all tests
before: (next) => next(),
after: (next) => next(),
// Before/After Hooks of test suites
beforeEach: (browser, next) => next(),
afterEach: (browser, next) => next(),
// To customize output report
reporter: (results, next) => next()
};
Dadurch können wir die Suite einfach umgestalten:
module.exports = {
'Search on google': (browser) => {
browser
.init()
.waitForElementVisible('body')
.setValue('input[type=text]', browser.globals.searchTerm)
.waitForElementVisible('button[name=btnG]')
.click('button[name=btnG]')
.pause(1000)
.assert.containsText('#main', browser.globals.movieName)
.end()
},
after: (browser) => {
browser.end()
}
};
Beachten Sie die spezifischen dynamischen „globals“-Variablen, die für jede Umgebung definiert sind. Sie sind sehr hilfreich, wenn Ihre Systemumgebungsvariablen benötigt werden.
Und parallel, wie ist das?
Unsere Konfiguration führt die Test-Suites bereits parallel aus, daher müssen wir nur eine neue hinzufügen. Erstellen wir eine Test-Suite nw/tests/nightWatchIsMovie.test.js wie folgt:
module.exports = {
'Go To google': (browser) => {
browser
.init()
.waitForElementVisible('body')
.setValue('input[type=text]', browser.globals.searchTerm)
.waitForElementVisible('button[name=btnG]')
.click('button[name=btnG]')
.pause(1000)
},
'Check movie name': (browser) => {
browser
.assert.containsText('.mod .kno-ecr-pt.kno-fb-ctx', browser.globals.movieName)
.assert.containsText('.mod ._gdf', '2004')
},
after: (browser) => {
browser.end();
}
};
Es gibt einen kleinen Unterschied zu dieser neuen Datei, wir haben viele Tests, die unsere Suite zusammenstellen.
Es führt erneut unsere Tests aus und voila!

Sie haben zwei Testsuiten gleichzeitig in zwei verschiedenen Chrome-Browsern gestartet.
Fazit & Nachher
Mit einer großartigen Konfigurationsdatei ist Nightwatch ein einfach zu bedienendes Tool.
Tatsächlich lässt sich die Minimalkonfiguration ziemlich schnell booten und die Testsuiten bleiben lesbar und einfach zu aktualisieren. Die Parallelisierungsfunktion hilft Ihnen, viel Zeit zu sparen!
Bonus, die Testergebnisse sind dank der in xUnit vorhandenen Ausgangsfunktionen direkt vom Terminal lesbar nw/berichte Verzeichnis.
In einem nächsten Artikel werden wir über das Pages-Objekt und die Entwicklung komplexer Befehle sowie einige andere Tipps zu Nightwatch sprechen.
Bleiben Sie dran …
