Selenium Grid mit Docker - Continuous Testing im Continuous Delivery Umfeld

🕒 Lesedauer: 15 Minuten

Im Rahmen einer Reihe von Blogartikeln zum Thema Continuous Testing im Continuous Delivery Umfeld starten wir hier mit einem Blog zu Selenium Grid mit Docker.

Ein entscheidendes Ziel von Continuous Testing ist es, dem Kunden schneller Softwareanpassungen getestet bereitstellen zu können und somit den veränderten Erwartungen gerecht zu werden. Um dies zu verwirklichen gibt es verschiedene Möglichkeiten. Ein effektiver Weg ist die Kombination aus Selenium Grid und Docker.

In diesem Artikel erklären wir Ihnen

  • was die beiden Tools machen
  • warum sie zusammen sehr sinnvoll sind
  • wie man sie installiert
  • erste Schritte (Starten Hub und Nodes)
  • was ist Docker-compose
  • wie funktioniert die Umsetzung (Beispiel)

Was ist Continuous Testing und Continuous Delivery

  • Continuous Testing

Continuous Testing ist der Prozess der Durchführung automatisierter Tests als Teil der Delivery-Pipeline (CI/CD) um kontinuierlich alle Veränderungen des Codes zu überprüfen, damit die Anforderungen (funktionale als auch nicht-funktionale (Lasttests und Performancetests)) validiert werden können.

  • Continuous Delivery

Continuous Delivery (CD) ist ein Software-Entwicklungs-Ansatz, welcher mit einer Sammlung von Prozessen, Techniken und Werkzeugen das Deployment (Softwareauslieferungsprozess) weitgehend automatisiert und kontinuierlich verbessert.

Zu den Techniken zählt man Continuous Integration (CI), Testautomatisierung und kontinuierliche Installation.

Hier eine Veranschaulichung einer CI/CD-Pipeline:

 

Image
testing-pipeline.png

Bild: Testing Pipeline (Klicken zum Vergrößern) [Quelle: Qytera]

 

Was ist Selenium bzw. Selenium Grid

Selenium

Möchte man Webanwendungen automatisiert testen, gibt es hierfür unterschiedliche Möglichkeiten. Eine sehr gute Wahl ist das Framework Selenium. Dieses inzwischen weit verbreitete, kostenfreie Tool gehört zu den bekanntesten quelloffenen Testwerkzeugen.

Mit Selenium kann man Interaktionen mit der Webanwendung aufnehmen, Automatisierungsskripts implementieren und diese beliebig häufig in Tests wiederverwenden. Man kann auch kompliziertere Vorgänge damit durchführen (z.B. in das Backend einloggen, erstellen von Datensätzen, u.v.m.).

Selenium Grid

Selenium Grid gehört zu der Selenium Suite und ist ausgerichtet auf den gleichzeitigen Test auf verschiedenen Browser-Instanzen. Somit kann durch Parallelität bei der Testdurchführung viel Zeit gespart werden.

Die Architektur von Selenium Grid wird Hub und Node-Architektur genannt. Dabei ist der Hub das Zentrum und nur auf einem Computer vorhanden und in ihn werden die Tests geladen. Die Nodes (Knoten) entsprechen den Selenium-Instanzen. Sie führen die Tests aus, welche auf dem Hub geladen wurden. Die Systeme mit den Nodes können auf anderen Plattformen laufen, als der Hub.

 

Image
selenium-hub.png

Bild: Selenium Hub. (Klicken zum Vergrößern) [Quelle: Qytera]

 

Was ist Docker

Das Docker Tool erleichtert es einem mit Hilfe von Containern eine Anwendung zu erstellen, bereitzustellen und auszuführen. Mit so einem Container kann ein Entwickler oder Test Automation Engineer eine Anwendung mit allen erforderlichen Teilen (z. B. Bibliotheken und anderen Abhängigkeiten) zusammenpacken und als ein Paket versenden. Auf diese Weise kann der Entwickler sicherstellen, dass die Anwendung auf jedem anderen Linux-Betriebssystem ausgeführt werden kann, unabhängig von der benutzerdefinierten Einstellung.

Docker hat ein ähnliches Prinzip eines abgeschlossenen Systems wie eine virtuelle Maschine. Virtuelle Maschine haben ein vollständiges Betriebssystem mit einer eignen Speicherverwaltung und zugehörigem Gerätetreiber. In einer virtuellen Maschine werden wertvolle Ressourcen für das Gast-Betriebssystem und den Hypervisor emuliert, wodurch es möglich ist, viele Instanzen eines oder mehrerer Betriebssysteme parallel auf einem einzelnen Rechner (oder Host) auszuführen. Jedes Gast-Betriebssystem wird als einzelne Entität vom Host-System ausgeführt.

Auf der anderen Seite werden Docker-Container mit Docker-Engine ausgeführt und nicht mit dem Hypervisor. Container sind daher kleiner als VMs und ermöglichen einen schnelleren Start mit besseren Performance.

Im Vergleich zu virtuellen Maschinen können Container schneller und weniger Ressourcen-intensiv sein. Bei einer virtuellen Maschine kann es einige Minuten dauern bis die Anwendungen gestartet sind, wobei ein Container in wenigen Sekunden erstellt und gestartet werden kann.

Installation (beschrieben für Windows)

Damit Docker für Windows richtig funktioniert, benötigt die Maschine:

  1. 64-Bit-Betriebssystem
  2. Windows 7 oder höhere Version (ebenfalls möglich mit MacOS und Linux)
  3. Hyper-V installiert und funktionsfähig (Standardmäßig normalerweise schon in Funktion)
  4. Virtualisierung aktiviert (Zu sehen und aktivieren im BIOS, falls nicht standardmäßig eingestellt)

Link: Docker für Windows 10, MacOS, Linux

Die Installation von Docker selbst ist einfach und für weitere Information kann man der Docker Installations-Dokumentation folgen. Es ist jedoch darauf zu achten, dass bei der Installation die Option "Windows-Container" ausgewählt wird.

Die Installation fügt dem Computer die folgende Software hinzu:

Docker Client für Windows
Docker Machine für Windows Terminals
Docker Compose
Docker Toolbox-Verwaltungstool und ISO
Oracle VM VirtualBox
Kitematic, the Docker GUI
Docker QuickStart shell
Git MSYS-Git UNIX-Tools

Überprüfung der Installation

Das Installationsprogramm fügt Docker Toolbox, VirtualBox und Kitematic dem Anwendungsordner hinzu.

Um ein vorkonfiguriertes Docker Toolbox-Terminal zu starten, klicke auf das Docker QuickStart-Symbol. Wenn das System eine Benutzer-Kontensteuerung anzeigt, damit Virtual-Box Änderungen an Ihrem Computer vornehmen kann, dann wählen Sie bitte Ja. Das Terminal führt mehrere Dinge aus, um Docker Toolbox für Sie einzurichten. Wenn es fertig ist, zeigt das Terminal die Eingabeaufforderung $ an.

 

Image
docker-wal.jpg

Bild: Docker Toolbox. (Klicken zum Vergrößern) [Quelle: Qytera]

 

Lassen Sie uns ein Beispielprogramm hello-world ausprobieren. Geben Sie den folgenden Befehl in der Eingabeaufforderung ein:

docker run hello-world

Dies sollte das sehr kleine hello-world Image herunterladen und eine Meldung mit "Hello from Docker" anzeigen, d.h. Docker funktioniert einwandfrei.

Im Hintergrund ist viel passiert, um Hello World zum Laufen zu bringen. Hier sind einige dieser Schritte.

  1. Die Anwendung Docker-Client wurde über den Docker-Befehl aufgerufen.
  2. Der Aufruf „docker run hello-world“ wurde ausgeführt.
  3. In diesem Fall wurde Docker Client aufgefordert eine Instanz eines Docker-Image mit dem Titel hello-world zu erstellen. Woher hat Docker dieses Image? Docker Client sucht in den lokalen Repositories nach dem Image mit dem Titel „hello-world“, kann es aber nicht finden. Daher sucht Docker nun im Internet in einem öffentlichen Repository von Docker Images, welches von Docker selbst gehostet wird. Dort ist Docker nun fündig geworden und hat es heruntergeladen, installiert und die Instanz gestartet.

Selenium Grid mit Docker Containern

Normalerweise müssen wir beim Konfigurieren des Selenium Grids mehrere virtuelle Maschinen als Node anlegen und jede einzelne Node mit dem Hub verbinden. Wenn wir ein normales Grid erstellen, müssen wir die Selenium Server JAR Datei herunterladen und diese JAR-Datei auf jedem Computer ausführen, auf dem wir das Selenium Grid einrichten wollen. Dies ist teuer und manchmal eine zeitaufwendige Aufgabe für die Tester. Docker hilft uns jedoch, kostenintensive und zeitaufwendige Probleme zu lösen.

 

Image
docker-mobile (1).png

Bild: Docker Mobile. (Klicken zum Vergrößern) [Quelle: Qytera]

 

Installiere die Docker Images

Wie beim normalen Grid müssen wir bei der Konfiguration des Selenium Grids mit dem Docker die Hub- und Browser-Nodes in unserem Docker-Container installieren. Später können wir den Hub und die Knoten aus diesen Docker-Container starten.

Daher müssen wir zuerst die Hub- und Node Images im Docker installieren.

  • Selenium/hub
  • Selenium/node-chrome
  • Selenium/node-firefox-debug (wichtig für nachvollziehen)
  • Selenium/node-chrome-debug

Die nächste Frage ist, wie man diese Images findet. Um diese Images zu finden, geht man zum Docker Hub und sucht nach einem Image mit dessen Namen. Diese Images kann man auch mit der Eingabe des Search-Befehls finden, wie unten angezeigt.

docker search Selenium/hub

 

Image
selenium-hub-docker.jpeg

Bild: Selenium Hub Docker. (Klicken zum Vergrößern) [Quelle: Qytera]

 

Man findet auf Docker Hub, bei der Suche nach Selenium/hub folgende Ergebnisse

 

Image
docker-screenshot1.jpeg

Bild: Docker Screenshot 1 (Klicken zum Vergrößern) [Quelle: Qytera]

 

Hier werden alle Image Repositories angezeigt, die wir für Selenium Hub haben. Hier müssen wir auf das Image klicken, das die größte Anzahl von Pulls aufweist. Es wird uns helfen, unseren Code ohne Fehler auszuführen.

Sobald wir auf ein Image klicken, sehen wir ein neues Fenster (siehe unten).

 

Image
docker-screenshot2.jpeg
Bild: Docker Screenshot 2 (Klicken zum Vergrößern) [Quelle: Qytera]


 

So kann man die anderen Images in Docker Hub suchen und entsprechende Infos holen.

Hier kann man jetzt einzelne Images aus der Docker Repository runterladen. Bitte führe diese einzelne Kommandos aus.

  1. docker pull selenium/hub
  2. docker pull selenium/node-firefox
  3. docker pull selenium/node-firefox-debug
  4. docker pull selenium/node-chrome
  5. docker pull selenium/node-chrome-debug

Nachdem wir alle Images herunterladen haben, können wir sie mit dem folgenden Befehl überprüfen.

docker images

Selenium Hub starten

Wir starten zuerst Selenium Hub aus dem Docker Container. Dazu benötigen wir folgenden Befehl.

docker run -d -p 4444:4444 --name selenium-hub selenium/hub

Um einen Container im getrennten Modus zu starten, verwenden wir die Option -d oder -d=true

Selenium Hub wird jetzt gestartet. Um dies zu überprüfen, müssen wir folgender Link im Browser eingegeben.

http://localhost:4444/grid/console

Beim Starten von Selenium Hub können Fehler auftreten. Verwenden Sie die Befehle "docker stop $(docker ps -aq)" und "docker rm $(docker ps -aq)", um alle Container zu stoppen und zu löschen. Dann starten Sie noch einmal.

Selenium Nodes starten

Es wird jetzt Chrome Node und Firefox Node gestartet und mit Selenium Hub verbunden.

Befehle zum Ausführen von Chrome Node von Docker:

 

Image
docker-screenshot5.jpeg
Bild: Docker Screenshot 5 (Klicken zum Vergrößern) [Quelle: Qytera]


 

Jetzt verbinden wir Debug Nodes mit Hub.

  • docker run -d -P -p 5901:5900 --link selenium-hub:hub -v /dev/shm:/dev/shm selenium/node-chrome-debug
  • docker run -d -P -p 5902:5900 --link selenium-hub:hub -v /dev/shm:/dev/shm selenium/node-firefox-debug

Nachdem die Debug Nodes in Chrome und Firefox ausgeführt sind, kann man den Browser aktualisieren. Nun findet man dort die beide Nodes.

 

Image
docker-screenshot6.jpeg
Bild: Docker Screenshot 6 (Klicken zum Vergrößern) [Quelle: Qytera]


 

Wenn bei der Ausführung von Images ein Fehler auftritt, sollte man das Image erneut installiert und erneut von Docker aus ausführen. Als nächstes Schritt beobachten wir die Debug-Nodes mit VNC-Viewer. Dafür brauchen wir einen VNC-Viewer. realvnc download Wir brauchen die Portnummern der Chrome- und Firefox-Debug-Node um diese Nodes mit VNC-Viewer zu verbinden.

docker ps -a

Portnummer 5901 für Chrome Node und Port 5902 für Firefox Node sind definiert. Wir rufen jetzt den installierten VNC Viewer auf und geben die Daten in folgendem Format ein: Hub-URL:Port Nummer z.B. 127.0.0.1:5901 (5901 für Chrome & 5902 für Firefox) Das vordefinierte Passwort ist secret

Nach dem Klick auf den Connect-Button fragt der VNC Viewer nach einem Passwort. Das Passwort ist secret. Danach sieht man ein Fenster wie bei einer VM (siehe unten)

 

Image
docker-screenshot8.jpeg

Bild: Docker Screenshot 8 (Klicken zum Vergrößern) [Quelle: Qytera]

 

Ebenso können wir das Gleiche im Firefox-Browser machen, indem wir den VNC-Viewer verwenden. So haben wir unsere Docker Installation mit Selenium Grid abgeschlossen.

Docker-compose YAML Datei

Wenn unsere Docker Anwendung mehrere Container enthält (z. B. komplexe Anwendungen mit einem Web Server, einer Datenbank), dann ist es umständlich jedes Mal auf Kommandozeilen-Ebene die Funktionen auszuführen.

Docker-compose löst dieses Problem, indem man in einer einzelnen YAML Datei die Multi Container Anwendung mit Abhängigkeiten definiert. Man kann es mit einem einzigen Befehl starten und stoppen.

Wir haben die Möglichkeit, den Prozess in der YAML-Datei zu definieren und mit dem Befehl docker-compose auszuführen. Als Beispiel wurde ein YAML Datei angelegt:

 

Image
docker-screenshot9.jpeg

Bild: Docker Screenshot 9 (Klicken zum Vergrößern) [Quelle: Qytera]

 

Dafür erstellt man einen neuen Ordner, unter diesem Ordner legt man die docker-compose.yml Datei zusammen mit dockerfile ab (man kann als Dateiendung sowohl .yml als auch .yaml verwenden, beide sind funktionstüchtig).

Mit docker-compose kann man diese Einstellung ausführen. Durch das Kommando docker-compose up -d werden die Images für Hub, Chrome und Firefox Nodes von Docker abgerufen und ein Instanz jedes verfügbaren Browsers gestartet. Standardmäßig wird die neueste Versionen verwendet wenn wir die Versionsnummer am Ende der Image weglassen.

Vor dem Ausführen des folgenden Codes muss sichergestellt werden, dass keiner der in der docker-compose.yaml Datei angegebenen Container schon gestartet ist. Dafür kann entweder jeder Container einzeln mit dem Befehl "docker container kill " und anschließend "docker container rm " gelöscht werden oder es kann Docker neu gestartet werden, sodass auch alle Container beendet werden. Danach kann folgender Befehl ausgeführt werden:

$ docker-compose up -d

Selenium-Grid mit Docker - Ein Beispiel

Anbei ist ein Beispiel Code. Dieser wurde angepasst, damit man den Code nicht lokal sondern auf Selenium Nodes ausführen kann.

 

Image
docker-screenshot10.jpeg

Bild: Docker Screenshot 10 (Klicken zum Vergrößern) [Quelle: Qytera]

 

Die vorgenommen Änderungen sind unten aufgeführt und beschrieben.

Details

DesiredCapabilities bietet die Möglichkeit, die Eigenschaften des Browsers festzulegen. So stellen wir Browsername, Plattform und Version des Browsers ein:

  1. DesiredCapabilities capability = DesiredCapabilities.chrome(); // Für Firefox --> DesiredCapabilities.firefox
  2. capability.setBrowserName("chrome"); // Für Firefox --> setBrowserName("Firefox")

Wenn die Tests im lokalen Browser ausgeführt werden, dann kann man diese Driver verwenden z.B. firefoxdriver, iedriver, chromedriver. Weil wir die Tests auf dem Browser des Remote-Computers ausführen, verwenden wir RemoteWebDriver.

  1. driver = new RemoteWebDriver(new URL(seleniumHubURL), capability); // seleniumHubURL--> Selenium hub URL z.B. http://127.0.0.1:4444/wb
  2. driver.get("http://selenium.webtesting.eu/");

assertTrue Assertion wird im Allgemeinen für die boolesche Bedingung "True" verwendet. Wenn es "False" zurückgibt, wird es fehlschlagen und die Software-Ausführung von dieser spezifischen Methode übersprungen.

assertTrue(driver.getTitle().startsWith(title)); // title --> "Selenium"

Weiterhin muss sichergestellt werden, dass alle Browser nach dem Ausführen der verschiedenen Tests wieder korrekt geschlossen werden. Bei jedem Test wird ein neuer RemoteWebDriver erstellt, der nach dem Ausführen eines Testes wieder gelöscht (driver.quit()) werden muss. Wird der Driver nicht korrekt gelöscht, ist ein zweites Ausführen des Testes nicht möglich, da eine nicht abgeschlossene Instanz des Browsers schon in dem Container läuft. Ein erneutes Ausführen wird dadurch blockiert. Der Code wurde dahingehend angepasst, dass der Driver nach jedem Test geschlossen wird.

 

Image
docker-screenshot11 (1).jpeg

Bild: Docker Screenshot 11 (Klicken zum Vergrößern) [Quelle: Qytera]

 

Epilog

Sie sind nun gerüstet für einen gelungenen Start in die Welt des parallelen automatisierten Testens. In weiteren Blogs wollen wir auf andere interessante Gebiete von Continuous Testing im Continuous Delivery Umfeld eingehen. Es wäre schön Sie dort wieder begrüßen zu dürfen.

 

Image
testmanagement-beratung-softwarequalitaet-qytera.png

Veröffentlicht am 29.Juli 2021

Aktualisiert am 21.August 2024

Wilson Campero

Geschäftsführer, Senior Testmanager

Wilson Campero ist IT-Unternehmer und Experte für Softwarequalität sowie ISTQB Certified Full Advanced Tester. Seit mehr als 20 Jahren ist das Testen von Software sein Spezialgebiet.