Mehr oder weniger gründliche Layout Tests haben wir schon immer gemacht. Schließlich sollen unschöne Fehler vor dem Start einer Webseite und nicht erst durch den Kunden gefunden werden. Trotzdem beschränken sich diese meist nur auf sporadische, manuelle Vorgehensweisen. Heutige Webseiten werden aufgrund von gestiegenen Anforderungen an Größe und Responsivität immer komplexer. Daher werden automatisierte Layout Tests, insbesondere für große Webseiten, immer interessanter. Im folgenden Artikel möchte ich einen grundlegenden Überblick über die verschiedenen Arten von automatisierten Layout Tests sowie erste Beispiele vorstellen.
Auswahl der Methodik
Grob lassen sich drei Methoden der Testautomatisierung unterscheiden. In Spezifikationstests werden Layouts anhand vorher definierter Regeln geprüft. Dies bedeutet, dass das Aussehen einer Webseite in einer eigenen Syntax separat definiert werden muss, was natürlich einen deutlichen Mehraufwand erzeugt. Eine Alternative zu den sehr umfangreichen Spezifikationstests sind der Cross-Browser bzw. der Regressionstest. Bei ersterem werden Layoutunterschiede einer Webseite zwischen verschiedenen Browsern automatisiert untersucht. Beim Regressionstest werden verschiedene Versionen einer Webseite auf Unterschiede getestet.
Zum automatisierten Testing gehört im weitesten Sinne auch das Testen auf fehlerfreie Syntax, z.B. mittels einer geeigneten IDE und das Testen auf Einhaltung von Standards. Der Github-Editor Atom ist sicher nicht nur diesbezüglich eine Empfehlung wert.
Im Folgenden möchte ich das Framework BackstopJS vorstellen, das für einfache Regressionstests gut geeignet ist. Als weiteres werde ich das Galen Framework vorstellen, das nicht nur spezifikationsbasiert arbeitet, sondern auch Regressionstests, Cross-Browser-Tests und sogar funktionale Tests ermöglicht.
BackstopJS
Immer wieder machen wir Änderungen und stellen nicht fest, dass diese auch Teile unseres Layouts betreffen, welche wir gar nicht beabsichtigt haben zu ändern. Daher schauen wir uns BacktopJS an, einen der bekannteren CSS-Regressionstests basierend auf JavaScript.
Zunächst einmal wird node.js vorausgesetzt. Nach erfolgreicher Installation auf eurem System wechseln wir in unser Projektverzeichnis (als Beispiel verwende ich das Bootstrap Projekt Cover), indem unser Webprojekt liegt und installieren BacktopJS mit dem node.js Paketmanager npm:
cd /path/to/project
npm install --save-dev backstopjs
Danach müssen wir unsere Konfigurationsdateien erstellen lassen. Dazu wechseln wir in das Verzeichnis node_modules/backtopjs
und führen den Befehl npm run genConfig
aus.
Unser Verzeichnis sollte nun wie folgt aussehen:
In der Datei backtop.json
finden wir die zentrale Konfigurationsdatei. Wir überschreiben die Demokonfiguration mit folgender:
{
"viewports": [
{
"name": "phone",
"width": 320,
"height": 480
},
{
"name": "tablet_v",
"width": 568,
"height": 1024
},
{
"name": "tablet_h",
"width": 1024,
"height": 768
},
{
"name": "desktop",
"width": 1920,
"height": 1080
}
],
"scenarios": [
{
"label": "My Test Page",
"url": "../../index.html",
"hideSelectors": [],
"removeSelectors": [
],
"selectors": [
".masthead",
".inner.cover",
".mastfoot"
],
"readyEvent": null,
"delay": 500,
"misMatchThreshold" : 0.1,
"onBeforeScript": "onBefore.js",
"onReadyScript": "onReady.js"
}
],
"paths": {
"bitmaps_reference": "../../backstop_data/bitmaps_reference",
"bitmaps_test": "../../backstop_data/bitmaps_test",
"compare_data": "../../backstop_data/bitmaps_test/compare.json",
"casper_scripts": "../../backstop_data/casper_scripts"
},
"engine": "phantomjs",
"report": ["CLI", "browser"],
"casperFlags": [],
"debug": false,
"port": 3001
}
Dort legen wir unter viewports
die zu testenden Displaygrößen fest: phone, tablet_v, tablet_h und desktop. Unter scenarios
legen wir die einzelnen Bereiche einer Webseite fest, die getestet werden sollen. Wir testen hier beispielsweise die Navigation, das Cover und die Fußleiste. Das ergibt 12 Testfälle (3 Testbereiche x 4 Viewports). Unter path
werden die Pfade der Screenshots festgelegt.
Nun können wir unsere Referenzbilder mit dem Befehl npm run reference
erstellen. Diese befinden sich dann unter backstop_data/bitmaps_reference
.
Wir können unseren ersten Test starten: npm run test
. Dieser vergleicht nun die Referenzbilder mit unserer jetzigen Version unserer Webseite. Da wir noch keine Änderung vorgenommen haben, sollten alle Tests natürlich erfolgreich sein:
Unter backstop_data/bitmaps_test
findet ihr nun eure Testbilder, die für diesen Testdurchlauf erzeugt wurden und mit den Referenzbildern verglichen wurden. Unter http://localhost:3001/compare/ erzeugt BacktopJS euch einen schönen, übersichtlichen Report zu dem Testdurchlauf.
Machen wir unsere ersten Änderungen und ändern den Innenabstand von Listenpunkten:
<style>
li {
padding: 5px;
}
</style>
Nach erneutem Ausführen npm run test
erhalten wir nun ein aktuelles Testergebnis:
Test completed...
8 Passed
4 Failed
Diesmal fallen alle 4 Viewportgrößen im Navigationstestfall durch. Im Report werden alle Testfälle mit Referenzbild, aktuellem Testbild und Differenzbild angezeigt. In unserem Beispiel haben sich die Navigationspunkte verschoben.
Ihr seht, BacktopJS ist einfach zu bedienen, Testfälle sind einfach zu erstellen. Das oben gezeigte Beispiel ist trivial, doch bei großen Projekten können Regressionstests einen enormen Vorteil bringen um unbeabsichtigt veränderte Teile einer Webseite zu entdecken.
Weitere Informationen zu BacktopJS gibt es auch auf dem Blog des Entwicklers Garris Shipon.
Galen Framework
Das Open-Source Framework Galen ist eine analytische Methode, um das Look and Feel einer responsiven Webseite zu testen und daher insbesondere für Testgetriebene Entwicklung (TDD) geeignet. In einer Spezifikationsdatei werden Angaben über das Layout in der Galen Spec Language definiert. Diese ist durchaus intuitiv und lässt sich auch ohne Vorkenntnisse gut verstehen. Galen kann dabei verschiedene mitgelieferte Viewports berücksichtigen. Eigene Viewports lassen sich problemlos definieren. Mittels Selenium Grid lassen sich die Tests automatisiert auf verschiedenen Systemen und Browsern testen. Darüber hinaus unterstützt Galen Bildvergleiche (sprich Regressionstests) und sogar funktionale Tests.
Galen lässt sich per npm installieren:
sudo npm install -g galenframework-cli
Oder ihr ladet euch Galen herunter und installiert es mit folgendem Befehl:
sudo ./install.sh
Ob Galen einwandfrei funktioniert könnt ihr mit folgendem Befehl testen:
galen -v
Zunächst definieren wir unser Layout in der Galen Spec Language, wir nennen die Datei homepage.gspec
:
@objects
header css div.masthead
brand css h3.masthead-brand
= Header =
@on all
brand:
inside header 40px top
@on mobile
brand:
centered horizontally inside header
Im ersten Teil definieren wir unsere Objekte, mit denen wir später arbeiten möchten. Dazu weisen wir diesem in der ersten Spalte einen Namen zu, in der zweiten legen wir die Auswahlmethode fest (zur Auswahl stehen id, css oder xpath) und in der dritten Spalte wählen wir unser Objekt aus. In unserem Beispiel mittels CSS-Selektoren.
Im Folgenden definieren wir eine Sektion, die wir Header nennen und in zwei Gleichheitszeichen einschließen. Sektionen dienen im wesentlichen dazu, unsere Regeln zu strukturieren. Mit dem Schlüsselwort @on, gefolgt von einem Viewport, leiten wir eine Testsequenz für eine bestimmte Bildschirmgröße ein.
Es sind verschiedenste einfache Regeln nutzbar wie near
, width
, inside
und height
. Eine Übersicht über aller verfügbaren Regeln gibt es hier.
In unserem kleinen Beispiel soll der obere Außenabstand des Logos genau 40 Pixel betragen. Außerdem soll das Logo in der mobilen Ansicht im Header zentriert werden.
Als Zweites kommt nun die Galen Test Suit Syntax zum Einsatz. In dieser werden Testsequenzen definiert. Außerdem lassen sich hier auch Einstellungen (wie etwa die Viewportgrößen) definieren. Wir legen uns unter testsuit.test
eine kleine Testsuit an:
Homepage on a small mobile device
http://localhost/index.html 320x600
check homepage.gspec --include "mobile,all"
Homepage on a tablet device
http://localhost/index.html 640x480
check homepage.gspec --include "tablet,all"
Homepage on a desktop device
http://localhost/index.html 1024x800
check homepage.gspec --include "desktop,all"
Wir definieren uns hier drei Testdurchläufe. In allen diesen drei Testdurchläufen wird unsere zuvor erstellte Testdatei als Quelle unserer Regeln angegeben. Geprüft wird hier jeweils auf anderen Viewportgrößen. Hier könnten wir nun auch verschiedene Browsertests definieren (auch über die Cloud, mittels Seledium Grid) und vieles mehr. Wir starten nun unseren Test:
galen test testsuit.test --htmlreport .
Wir geben zum einen den Pfad zur Testsuit an, zum anderen, dass Galen uns einen HTML-Report erstellen soll. Während der Test durchläuft, öffnet sich immer wieder der Browser in den verschiedenen Bildschirmgrößen. Unser Testfälle sind schließlich erfolgreich:
========================================
Test: Homepage on a small mobile device
========================================
check homepage.gspec --include "mobile,all"
= Header =
brand:
inside header 40px top
centered horizontally inside header
========================================
Test: Homepage on a tablet device
========================================
check homepage.gspec --include "tablet,all"
= Header =
brand:
inside header 40px top
========================================
Test: Homepage on a desktop device
========================================
check homepage.gspec --include "desktop,all"
= Header =
brand:
inside header 40px top
========================================
----------------------------------------
========================================
Suite status: PASS
Total tests: 3
Total failed tests: 0
Total failures: 0
Unser HTML-Report sieht wie folgt aus:
Um einen Fehler zu provozieren ändere ich den Außenabstand des Headers zur oberen Bildschirmkante auf 20px:
@on all
brand:
inside header 20px top
Nach erneutem Testdurchlauf erhalten wir Fehlermeldungen:
Mit Klick auf die Tests können wir uns den Fehler genauer anschauen:
Das Schöne an Galen ist auch, dass von der betroffenen Stelle auf der Webseite eine Heatmap erstellt wird:
Dieses Beispiel sollte lediglich als Einführung in ein eigenes komplexes Thema dienen. Wer sich tiefer in das sehr mächtige Framework einlesen möchte, dem sei der Artikel des Galen Entwicklers Ivan Shubin auf Smashing Magazine empfohlen. Auch eine zehnteilige Videoreihe von ihm ist auf Youtube verfügbar.
Fazit
Die Komplexität von Webseiten steigt, durch moderne Testwerkzeuge lässt sich das automatisierte Testen aber immer komfortabler und schneller realisieren. In welchem Fall das trotzdem noch recht aufwendige Testen gerechtfertigt ist, muss von Fall zu Fall entschieden werden. Meines Erachtens macht es nur bei sehr komplexen und langlebigen Projekten Sinn. Projekte, bei denen hohe Qualität und Konsistenz an erster Stelle stehen.
Schreibe einen Kommentar