Testautomatisierung hat in den letzten Jahren eine immer größere Bedeutung in IT-Projekten bekommen und sich als fester Bestandteil im DevOps-Umfeld etabliert. In diesem Artikel wird der Einsatz von Selenium als Testautomatisierungs-Tool für die Software-Qualitätssicherung einer Webanwendung aufgezeigt. Des Weiteren erfolgt eine Beschreibung der Integration mit Docker zur Testausführung in virtualisierten Umgebungen.

Der Einsatz von Testautomatisierung in IT-Projekten basiert meist auf der Anforderung, agile Softwareprojekte im Unternehmen durchzuführen. Durch die häufigen Releases und kurzen Release-Zyklen in agilen Projekten wird die Anzahl von Deployments deutlich höher als bei Projekten, die nach klassischen Vorgehensweisen durchgeführt werden. Ist es nun der Anspruch, jedes Software-Release vollständig auf seine Funktionsfähigkeit zu testen, steigt der Zeit- und Kostenaufwand enorm an. Umfangreiche Tests sind dann kaum mehr zu stemmen, wodurch eine hohe Testabdeckung kaum noch möglich ist. Darüber hinaus ist das manuelle Reproduzieren von Testfällen als reine Fleißarbeit anzusehen, was früher oder später zu einer hohen Fehleranfälligkeit führen wird.

Die Automatisierung von Testfällen ist zwar ebenfalls mit Aufwand verbunden, da die Testautomatisierung meist ein eigenes Softwareprojekt ist, jedoch wird sich ihr Einsatz mittel- bis langfristig rentieren und somit eine Kostenersparnis gegenüber dem ständigen manuellen Testen mit sich bringen. Dennoch sollte die Testautomatisierung stets durch manuelle Tests von Fachexperten ergänzt werden, da sie ausschließlich die im Vorhinein festgelegten Testkriterien abdeckt. Ein manueller Tester schaut meist auch rechts und links von den definierten Testfällen. Ist die Testautomatisierung einmal implementiert, lässt sie sich beliebig oft durchführen, beispielsweise nach jedem Deployment auf einer QA-Instanz. Der manuelle Aufwand beschränkt sich dann ausschließlich auf die Auswertung der generierten Testberichte.

Selenium

Selenium ist ein Framework für die Erstellung von automatisierten OberflächenTests von Webanwendungen. Selenium ist primär ein Werkzeug, um die Benutzeroberfläche einer Anwendung zu testen. Durch die Überprüfung des Frontend können allerdings auch die Anwendungslogik und die anzuzeigenden Daten zumindest indirekt getestet werden. Für ausführliche Backend-Tests und Abfragen zur Datenqualität ist Selenium jedoch nicht geeignet. Der Einsatz von Selenium als Testwerkzeug bietet die Möglichkeit, sowohl Testsequenzen mit der Selenium IDE aufzuzeichnen und abzuspielen, als auch, diese programmatisch zu erstellen. Selenium unterstützt hierfür mehrere Programmiersprachen, unter anderem Java, C# und Python. Die Programmierung der Testfälle bietet hierbei einige Vorteile gegenüber der Testaufzeichnung. So können im Code Validierungs- und Verifikationspunkte festgelegt und eingebaut werden, während die Testaufzeichnung in der Regel „nur durch die Oberfläche klickt und tippt“ und die Anwendung auf reine Funktionalität testet. Der Einbau von Validierungen ermöglicht eine bessere Überprüfung vorher definierter Akzeptanzkriterien. Wird beispielsweise eine Produkt-Liste in einem Webshop ausgewertet, kann eine Validierung sicherstellen, dass nicht zu viele oder zu wenige Produkte in der Liste angezeigt werden. Mit einer Testaufzeichnung ist diese Validierung nicht möglich. Das Definieren der Akzeptanzkriterien im Vorhinein verbessert zudem das gewünschte Ziel-Bild der Anwendung und sorgt dafür, dass es unter verschiedenen Stakeholdern dasselbe Verständnis darüber gibt, wie die Anwendung aussehen soll. Weiterhin lassen sich codebasierte Testfälle besser strukturieren, wiederverwenden und warten. Durch die Modularisierung von Code-Bausteinen sind die Testfälle deutlich eigenständiger nutzbar. Gerade die Wiederverwendbarkeit von Code und die Anpassung an neue Anforderungen ist bei programmierten Tests von Vorteil. Weiterhin lässt sich im Code die Identifizierung der Elemente besser steuern. Insbesondere wenn Web-Elemente keine eindeutige ID haben, tendieren Aufzeichnungstools zur Nutzung von relativen oder absoluten Pfaden. Bei der Programmierung ist eine stückweise Ermittlung des Elements oftmals sinnvoller. Gerade bei sehr beweglicher Software sind die aufgezeichneten Tests später nicht mehr verwendbar. Ein weiterer erheblicher Nachteil von aufgezeichneten Tests ist die fehlende Möglichkeit, diese in einem Container auszuführen. Für das Programmieren der Testfälle nutzt Selenium das WebDriver API. Unterstützt werden alle gängigen Browser wie Chrome, Firefox, Safari, Edge, IE und Opera. Bei der Erstellung von Cross-Browser-Tests sind insbesondere die Umgebungsvoraussetzungen für die jeweiligen Browser zu beachten. So benötigt Safari ein Apple-Betriebssystem, sofern man die neueste Safari-Version nutzen möchte. Vor der Programmierung der Testfälle ist es wichtig, sich eine gute Vorgehensweise zu überlegen, wie die Tests sinnvoll gruppiert und zugeordnet werden können. Liegt ein gut konzipiertes Testmanagement vor, lassen sich die Testfälle im Anschluss besser warten und gegebenenfalls bei Änderungen anpassen. In diesem Zusammenhang sollte das Page Object Model (POM) genutzt werden. Das POM kann als Java-Abbild einer HTMLSeite betrachtet werden. Im POM werden im Regelfall die Web-Elemente durch findElement(By.id(„field1“)) ermittelt. Abgesehen von der ID eines Elements können Web-Elemente auch mittels css, xpath, class etc. gefunden werden. Ziel des POM sollte es sein, eine Java-Klasse zu haben, in der alle benötigten Elemente je einer HTML-Seite abgebildet werden. Damit die Tests nach fertiger Entwicklung ausgeführt werden können, wird zunächst eine ausführbare Datei (.jar bei Java) benötigt. Diese kann mit einem Build-Tool wie Maven erstellt werden. Das .jar-File kann an einem zentralen Ort, beispielsweise auf dem RepositoryManager Nexus abgelegt werden. Der Einsatz eines Nexus bietet den Vorteil, dass sowohl die Docker-Container (lediglich für Firefox und Chrome Tests) als auch weitere Clients auf die Datei zugreifen können. Beim Starten der Tests wird dann das entsprechende .jar-File übergeben. Sofern die Anwendung parametrisiert ist, sollten diese beim Start gesetzt werden, wenn dies von den Default-Einstellungen abweicht.

java -Dtest.env={dev|local|qa} -jar .\target\selenium.jar 

Listing 1: Anwendung mit Parametern starten

Das Beispiel in Listing 1 startet die Anwendung mit dem Setzen des Parameters test.env. Weitere Parameter können dabei ergänzt werden. Bei Nutzung des Selenium WebDriver empfiehlt es sich, den RemoteWebDriver zu nutzen und den für den Testfall gewünschten Browser als Parameter zu übergeben. Auf dessen Basis wird dann im Programm der entsprechende browserspezifische WebDriver erstellt. Bei der Erstellung der browserspezifischen Driver ist darauf zu achten, dass die Browser-Profile unterschiedlich erstellt werden. Eine wichtige Einstellung ist unter anderem das Erlauben der Ortungsfunktion, sofern bei der zu testenden Applikation eine Standortermittlung vorliegt. Neben der Erzeugung des WebDriver sollten in einer Browser-Klasse zentrale Browser-Funktionen ausgelagert werden, die in mehreren Testfällen genutzt werden. In der folgenden Liste sehen Sie einige Beispiele, die in keiner Browser-Klasse fehlen sollten:

  • getTitle()
  • getUrl()
  • loadPage()
  • openNewTab()
  • getScreenshot()
  • confirmAlertMessage()

Die Funktion getScreenshot() ist insbesondere im Fehlerfall äußerst wichtig, da es sich empfiehlt, die Reports um entsprechende Screenshots (siehe Abschnitt Cucumber) der Anwendung zu erweitern.

Docker

Bei Docker handelt es sich um eine Container-Technologie, die es ermöglicht Linux-Container zu erstellen, zu betreiben und zu verwalten. Docker versteht sich als eine Art leichtgewichtige und modulare virtuelle Maschine. Docker Container können flexibel skaliert und auf einem Zielsystem beliebig oft kopiert und gestartet werden.

Für das Ausführen der Tests im Docker Container müssen vorher die Docker Images (je eines für Chrome und Firefox) erstellt werden. Die Dockerfiles zur Erstellung der Images finden Sie in mehreren GitHub-Projekten. Falls Sie eine bestimmte Version des Browsers testen möchten, ist darauf zu achten, dass Sie zu der Browserversion eine kompatible Version des entsprechenden Drivers nutzen.

Sobald Sie das Dockerfile heruntergeladen haben können Sie das Image wie in Listing 2 beschrieben bauen.

docker build . -t applicationtest

Listing 2: Docker Image bauen

Zum Starten der Tests aus dem Docker Container heraus verwenden Sie den Aufruf aus Listing 3.

docker run --rm --shm-size 2g -e TESTENV_PARAM="dev" --name applicationtest -it applicationtest

Listing 3: Docker Tests starten

Die Integration in Jenkins (oder einem anderen CI-System) sorgt anschließend u.a. dafür, dass die Tests nicht nur automatisiert ausführbar sind, sondern dass sie bspw. auch automatisiert getriggert werden. Neben dem zeitgesteuerten Build zu einem festen Zeitpunkt kann auch das zentrale Repository abgefragt werden. Die Tests bedürfen somit keinem manuellen Anstoß.

Cucumber

Cucumber ist ein Tool, welches das Behavior-Driven-Development (BDD) unterstützt und aus dem Umfeld des automatisierten Testens entstand. BDD basiert darauf, Software auf Basis von definierten Akzeptanzkriterien zu entwickeln. Diese Akzeptanzkriterien dienen als kommunikative Basis zwischen dem Entwicklerteam und den übrigen Stakeholdern. Akzeptanzkriterien werden in natürlicher Sprache festgehalten, sodass sowohl Fachanwender als auch Informatiker und Programmierer diese verstehen. Dies führt zudem zu einem gemeinsamen Verständnis aller Projektbeteiligten. Das Überführen der Anforderungen von natürlicher Sprache nach Programmcode ist Aufgabe der Softwareentwickler.

Cucumber versteht sich selbst als eine Schnittstelle zwischen der IT und der Fachabteilung. Mithilfe von Cucumber wird an genau der Stelle angesetzt, in der es darum geht fachliche Anforderungen aus der natürlichen Sprache in Programmcode zu überführen.

Abbildung 1: Cucumber-Datei

Cucumber führt die Anforderungsanalyse und das automatisierte Testen durch die Gherkin-Notation zusammen. Der Entwickler programmiert anschließend die zerlegte Schritt-für-Schritt Anforderung in die Programmiersprache seiner Wahl aus.

In Abbildung 1 ist eine für Cucumber erstellte Feature-Datei zu sehen. Ein Szenario repräsentiert dabei ein vorher definiertes Akzeptanzkriterium innerhalb der Produktanforderungen. Das Akzeptanzkriterium wird anschließend in mehrere Schritte (engl. Steps) unterteilt.

Abbildung 2: Steps-Datei

Hinter einem Step verbirgt sich dann letztendlich Programmcode in der jeweiligen Programmiersprache, z.B. Java. Ein Beispiel für das „Umwandeln“ eines Steps in eine Java-Funktion ist in Abbildung 2 zu sehen.

Nach der Testdurchführung wird in einem generierten HTML-Bericht der Test farblich mit einem Status gekennzeichnet. Hierbei wird jeder einzelne Schritt aus Abbildung 1 markiert, sodass später klar erkennbar ist, welcher Testschritt zu einem Fehler geführt hat. Optional lassen sich die Berichte um Bilder, z.B. Screenshots der Applikation erweitern.

Durch die Nutzung von Cucumber als Bibliothek und dem Cucumber-Plugin für Jenkins, können die benötigten Reports bereits out-of-the-box und ohne große Zusatzentwicklung erstellt werden. Neben den Step-für-Step Report bietet Cucumber auch direkt eine „managementgerechte“ Übersicht als Donut-Chart (siehe Abbildung 3) an bzw. auch eine Auflistung z.B. nach Tags.

Abbildung 3: Übersicht der Testfälle als Donut-Chart

Die Nutzung von Tags in Cucumber bietet die Möglichkeit, die Tests besser zu gruppieren. Außerdem können die Tests auch tag-gesteuert ausgeführt werden (siehe Listing 5), d.h. es müssen nicht zwingend immer alle Tests auf einmal durchgeführt werden.

docker run --rm --shm-size 2g -e TESTENV_PARAM="dev" -e CUCUMBERTAG_PARAM="@tag" --name applicationtest -it applicationtest

Listing 5: Docker Tests mit Tag „@tag“starten

Dies vereinfacht zum einen die Entwicklung, zum anderen ist es einfacher die Tests über ein bestimmtes Tag auszuwerten und sich den Trend über einen spezifischen Bereich der Applikation anzuzeigen.

Dieser Artikel wurde in der Ausgabe 4/2019 im DOAG RedStack Magazin veröffentlicht.

Jetzt teilen auf:

Jetzt kommentieren