Im ersten Teil unserer Artikelreihe haben wir euch die Vorteile automatisierter Oberflächentests, die Besonderheiten des Test-Frameworks Selenium sowie das Vorgehen damit beim lokalen Testen dargelegt. Für weniger anspruchsvolle Zwecke sollte das bis dahin vermittelte Wissen auch ausreichend sein, um im kleinen Rahmen schnell und einfach eine erste Lösung aufzusetzen. Das volle Potenzial der Testautomatisierung kann sich jedoch erst in einem Selenium Grid am besten entfalten. Damit wird nämlich auch eine saubere Lösung in Richtung Continuous Delivery möglich.
Mit Selenium Grid verteilt und parallelisiert testen
Die Selenium Grid-Architektur baut im Prinzip auf einen Proxy-Ansatz auf, der vereinfacht ausgedrückt, die Weiterleitung der Tests von einem Punkt an entfernt liegende Punkte ermöglicht. Das Ziel dahinter ist, eine einfache Möglichkeit zu bieten, Tests verteilt und auf mehreren Rechnern parallel ausführbar zu machen.
Hub + Node(s) = Selenium Grid
Im Selenium Grid gibt es dazu die beiden Rollen Hub und Node, die ihre entsprechende Rolle beim Start einer Selenium-Instanz zugeteilt bekommen. Ein Selenium Hub wird dabei mit mehreren Selenium Nodes zu einem Grid zusammengefasst.
Der Hub ist der verwaltende Teil des Grids, d.h. er vermittelt die an ihn zugetragenen Testskripte ressourcen- und bedarfsgerecht an die ihm bekannte Nodes.
Die Nodes wiederum führen die vom Hub übermittelten Testskripte aus. Vorher jedoch registriert sich jeder Node direkt am Hub und teilt seine individuelle Testkonfiguration mit, wie z.B. welchen Browser und Browserversion er unterstützt oder welches Betriebssystem darauf installiert ist (siehe nachfolgende Abbildung).
Dieser Architekturansatz hat zudem den Vorteil, dass die Testkonfigurationen aus dem direkten Umfeld der Testskripte gelöst zentral an einer Stelle (Hub) verwaltet werden. Das sorgt nicht nur für eine saubere Trennung, sondern die Testskripte lassen sich gleichzeitig auf einer Vielzahl von unterschiedlichen Umgebungen ausführen.
Der Allrounder unter den WebDrivern: RemoteWebDriver
Beim lokalen Testen mit Selenium interagieren die Testskripte unter Verwendung eines browserspezifischen WebDrivers (FirefoxDriver, ChromeDriver, etc.) direkt mit dem dazugehörigen Browser und der vorgegebenen Testkonfiguration.
In einem Selenium Grid bedient man sich jedoch der konkreten WebDriver-Implementierung RemoteWebDriver. Dieser steht zusätzlich zu den übrigen WebDriver-Implementierungen zur Verfügung und bietet als einziger WebDriver die Möglichkeit, Testskripte ferngesteuert auf beliebig vielen und unterschiedlich konfigurierten Testrechnern ausführen zu lassen. Damit lassen sich nicht nur der Hub in einem Grid ansprechen, sondern auch verteilte Container-Lösungen (wie Docker) oder ein externer Testrechner, der sich nicht in einem Grid befindet.
Die Funktionalität im Überblick
Wie bereits beschrieben, interagieren die Testskripte mit dem Hub mittels des speziellen RemoteWebDriver. Vor jedem Testlauf kann der Hub anhand einer zusätzlich übergebenen DesiredCapabilities-Klasse erkennen, welche Anforderungen ein Testskript an die Testrechner-Konfiguration hat, auf dem es laufen soll.
Auf Basis dieser Informationen sucht der Hub unter den bei ihm registrierten Nodes (sowie deren mitgeteilten Konfigurationen) nach den angeforderten „Capabilities“ und findet hoffentlich einen Node, der diese erfüllen kann. Danach läuft alles wie gehabt. Der Hub übermittelt die vom Testskript erhaltenen Testbefehle an den Node, worauf der Node über den bei ihm laufenden browserspezifischen WebDriver die Befehle im entsprechenden Browser ausführt.
Selenium Grid im CI-Prozess
Ebenso werden auf die Funktionalitäten des Selenium Grids zugegriffen, um die automatisierten Oberflächentests in den Entwicklungsprozess einzubinden.
Im weit verbreiteten CI-Tool Jenkins kann ein solcher CI-Grid mit Hilfe eines OpenSource Plug-Ins eingerichtet werden. Das Plug-In richtet auf dem Jenkins-Server ein Selenium Grid ein und erstellt gleichzeitig auf dem Jenkins-Master einen Hub.
Die Installation stößt man einfach über die Jenkins-Weboberfläche („Manage Jenkins / Manage Plugins“) an. Nach erfolgter Installation erscheint die Erweiterung in der Seitenleiste des Jenkins-Dashboards. Mit einem Klick darauf erhält man Informationen über den aktuellen Status des Hubs, wie z.B. erfolgte Konsolenausgaben oder einen Überblick über die Nodes, die sich am Hub registriert haben. Auch findet man dort die WebDriver-URL, von den Testskripten für Testläufe genutzt werden muss, damit diese im CI-Grid laufen können.
Zudem bietet die Erweiterung die komfortable Möglichkeit, Jenkins-Slaves direkt über die Jenkins-Weboberfläche zu Nodes zu konfigurieren und diese über wenige Klicks dem Grid hinzufügen. Die Konfigurationsmöglichkeiten eines Nodes können auf der Jenkins-Weboberfläche teilweise limitierend sein (bspw. weniger Browserauswahl). Mit einer selbst erstellten JSON-Datei, die als Konfiguration herangezogen wird, kann die Konfiguration eines Nodes individuell festgelegt werden. Heutzutage werden Testrechner zumeist auch außerhalb der CI-Infrastruktur aufgesetzt, die nach Bedarf angefordert werden (z.B. in der Cloud). In diesen und ähnlichen Fällen müssen die externen Nodes sich eigenständig direkt am CI-Hub registrieren.
Fazit
Nun haben wir viel von Testautomatisierung geschwärmt. Doch eines muss festgehalten werden: Das manuelle Testen sollte nicht komplett aufgeben werden. Stattdessen sollte dieser wichtigen Tätigkeit in der Qualitätssicherung ein höherer Sinn verliehen werden. Dies kann beispielsweise dadurch geschehen, in dem vorhandene Skills in interessanteren und wertschaffenderen Aufgaben eingesetzt werden wie Usability Testing, User Experience Analysen, Testfalldesign, etc. Denn für stupide, monotone Tätigkeiten kosten diese Spezialisten enorm wichtige Ressourcen: Zeit, Geld und Nerven.
Wenn also Software routiniert und immer wieder auf die exakt gleiche Art und Weise auf mögliche Fehler geprüft werden soll, sind automatisierte Tests unschlagbar. Sie sind nicht nur schneller, beständiger und langfristig ressourcenschonender, sondern im Vergleich zum manuellen Testprozess exakt und beliebig oft wiederholbar und entsprechen genau den Anforderungen der immer kürzer werdenden Entwicklungszyklen.
Diese Artikelreihe sollte daher aufzuzeigen, wie einfach Testautomatisierung mit Selenium möglich ist. Das Ziel war dabei nicht nur einen kompakten Überblick über die Thematik zu geben, sondern auch dafür zu sorgen, ein umfassendes Verständnis des Selenium-Konzepts zu vermitteln, um schlussendlich euch zu motivieren, den ersten Schritt auf dem Weg zu automatisierten Oberflächentests zu machen.
In diesem Sinne: Frohes Testen!
1 Kommentar
Pingback: Automatisierung von fachlichen UI-Tests mit Selenium (1/2) | The Cattle Crew Blog