PageObjects, die Seele(nium) eines Frameworks

PageObjects, die Seele(nium) eines Frameworks

photo credit: faungg's photo via photopin cc
photo credit: faungg’s photo via photopin cc

Die ersten Gehversuche werden oft mit der Selenium IDE gemacht. Sicher kein schlechter Ansatz, um die Möglichkeiten von Selenium spielerisch kennenzulernen. Sobald aber zum Beispiel die Struktur der Anwendung geändert wird oder Tests erweitert werden, kann es passieren, dass der einmal gemachte Test obsolet wird und neu aufgenommen werden muss. Nachdem sich die Tests der Anwendung anpassen sollen und nicht umgekehrt kann im Frontend der Anwendung die Benennung der Selektoren geändert werden.

Was ist zu tun? Alle Tests die davon betroffen sind müssen angepasst werden. Ok evtl. kann das mit Search and Replace angepasst werden. Wenn das aber ständig passiert führt das oft zu Frustration und ständiger Anpassung von Tests und irgendwann lässt man das Testen ganz sein. So eine Situation kann entstehen, wenn die Tests direkt mit der Applikation gekoppelt sind.

 

Ein Framework zur Hilfe

Sicherlich, das Aufnehmen von Test ist am Anfang schnell und somit kosten sie wenig Zeit und Geld während der Entwicklung. Mit fortschreitender Zeit und Komplexität lohnt sich ein Framework, der vieles kapselt und Wiederverwendung fördert.

Die Lebenszeit eines Tests ist eng mit der Verzahnung mit der Applikation gekoppelt. Ein Framework verlängert hier die Lebenszeit eines Tests um, ein zigfaches, da Tesst nur noch vom Framework abhängen und nicht direkt von der Anwendung. Nötige Anpassungen, um Tests wieder laufähig zu machen, falls Änderungen in der Oberfläche passieren, werden zentral am  vorgenommen. Beispielsweise wird die Lokation eines DOM Objektes nur einmal als Methode generiert, es ist dann nur eine Anpassung nötig und der Wartungsaufwand wird gesenkt. Bei „record and replay“ mittels Selenium IDE, ist dieses Vorgehen nicht immer möglich.

TDD und Framework

Kombiniert man Test Driven Development und die Erstellung eines Frameworks für eine Applikation ergibt sich hierbei ein zusätzlicher Vorteil. Angenommen ein Formular auf einer Seite soll befüllt werden, so ist es nötig die einzelnen Inputfelder anzusteuern, zu befüllen und zu testen, ob in diesen auch das steht, was ursprünglich befüllt worden ist.

Wird dieses Muster für alle Bedienmöglichkeiten atomar genutzt ergeben sich bei der Entwicklung unzählige kleine Tests. Diese sind wiederholbar und können regelmäßig ausgeführt werden können. Hierbei kann ein Continous Integration Server, wie z.B. Jenkins, perfekte Dienste erweisen.

Zwar stehen diese Tests in keinem bestimmten Testkontext, sie geben aber Aufschluss darüber, inwieweit Teilbereiche funktionieren oder auch nicht. Was zu frühem Feedback für den Framework Entwickler führt und so können zeitnah gezielte Anpassungen  geschehen, falls Änderungen an der Bedienung oder Lokalisierung von Interaktionsobjekten stattfinden.

Es sollte bei der Entwicklung bedacht werden, dass nicht nur die fertige Applikation in Produktion in Regression getestet wird, um die Funktionsweise sicherzustellen. Viel mehr ist es wichtig vor einem Livegang in einer Staging Area das neue Inkrement zu testen und sicherzustellen, dass die Funktionsweise aus der vorhergehenden Version noch sichergestellt ist, am besten noch bevor manuelle Tester z.B. zusätzlich das Layout überprüfen.

Das test getriebene Vorgehen bei der Entwicklung kann ich persönlich nur empfehlen, auch wenn anfangs der Benefit noch nicht so groß ist. Sobald aber hunderte von Tests regelmäßig und in kurzen Iterationen durchführbar sind, ergibt das mittel- bis langfristig ein großes Auffangnetz auf das sich der Entwickler bei Änderungen verlassen kann.

Ein ähnlicher Ansatz kann sein aus wirklichen Tests das Framework aufzubauen und nach und nach immer mehr Funktionalität einzubauen. Hierbei ist der Vorteil, dass nur so viel Framework Code erstellt wird, wie wirklich benötigt wird. Je mehr Regressionstest für den Aufbau des Frameworks herangezogen werden, desto mehr Code kann wiederverwendet werden und nach und nach zahlt sich die Investition aus. Dieser Ansatz ist sehr sinnvoll, wenn in einem Team kein eigens für das Framework abgestellter Entwickler eingesetzt wird und eine automatische Testabdeckung vor dem Deployment gefordert wird.

 

Selenium PageObject

Aber wie am Besten beginnen. Meiner Erfahrung nach ist es eine gute Idee, wie ein User zu denken und so das Framework aufzubauen. Es ist dabei sehr gut bevor überhaupt eine Zeile Code geschrieben ist, sich mit der Anwendung vertraut zu machen und anhand von bereits vorhandenen manuellen Tests durch die Applikation zu klicken. Dies dient dazu zu verstehen, was der User auf der Applikation versucht zu erreichen und eine Idee für PageObjects zu bekommen.

Betrachtet man die Applikation, die zu testen ist, gibt es immer eine Startseite, auf der der Benutzer landet und seine Reise beginnt. Diese Seite kann als erstes PageObject betrachtet werden, die als Klasse abstrahiert werden kann. Auf dieser Seite können Formulare vorhanden sein, daraus können wiederum eigene Subklassen entstehen, um eine natürliche Abstraktion sicherzustellen.

pageObjectDiagram

Legt man den Focus nun z.B. auf die Navigation können aus den Seiten hinter den einzelnen Links weitere PageObjekte entstehen, mögliche Kandidaten wären z.B. ein Warenkorb oder die Ergebnisseite eines Shops. Eine Regel, um eine Klasse abstrahieren zu können ist, wenn für ein Objekt der Applikation ein natürlicher Begriff gefunden werden kann, mit dem man Funktionalität verbindet. Wie im Beispiel einer Login Seite das befüllen von Formularfeldern mit User und Nachname und dem obligatorischen Klick auf ein Login Button.

Ist ein PageObject erstmal gefunden, sollte der nächste Schritt sein, zu analysieren, ob die Seite eine komplexe oder eher einfachere Struktur besitzt. Ist die Struktur eher einfach und beinhaltet z.B. nur ein Formular mit wenig Eingabefeldern kann mit der Umsetzung der Funktionalität begonnen werden. Ist die Seite eher komplexer und besteht sie aus mehreren Interaktionsmöglichkeiten ist es angebracht, diese Strukturen in SubPageObjects abzubilden. Hier liegt die Kunst darin eine gute Balance zu schaffen zwischen Vereinfachung und auf der anderen Seite Überstrukturierung.

Auch wenn das Vorgehe ein bisschen robotisch wirken mag, ist es ein gutes Muster, das von Seite zur Seite wiederholt werden sollte, um so wenig wie möglich Codedoppelung zu erreichen und um den Aufwand der Pflege eines solchen Frameworks auf ein Minimum zu reduzieren.

 

Selenium GRID

Ist die Hürde erstmal geschafft, dass die nötigsten Objekte und Funktionalität herausgearbeitet wurden, fällt auf, dass durch das testgetriebene Entwickeln viele Tests entstanden sind.  Am Anfang konnte das Framework innerhalb weniger Minuten bei Änderungen durchgetestet werden. Je tiefer die Tests durch z.B. einer Buchungstrecke verlaufen, desto mehr PageObjekte werden passiert. Dies kann die Entwicklungsgeschwindigkeit und die Qualität senken, da zu wenig oder zu spät getestet wird. Natürlich möchte man als Entwickler schnell Ergebnisse sehen, um festzustellen, ob der Code das tut, was erwartet wird.

Das Ziel sollte sein, auch bei kleinen Änderungen am Framework schnell Feedback zu erhalten. Aber 5 bis 20 Minuten für kleine Änderungen auf ein Ergebnis zu warten ist einfach eine viel zu lange Zeitspanne. Spätestens jetzt sollte über Beschleunigung der Tests nachgedacht werden.

Wenn der eigene Rechner nicht reicht und die Tests den eigenen Entwicklungsrechner in die Knie zwingt, kann eine Virtual Machine mit mindestens 4 CPUs gute Dienste erweisen. Am besten ist es über mehrere virtuelle Maschinen im Netzwerk zu verfügen und falls möglich für parallele Ausführung verschiedener Testmethoden auf diese Rechner zu sorgen. So können auch mit Hilfe des Frameworks erzeugte Regressionstest innerhalb kurzer Zyklen wiederholt und Probleme früh erkannt werden.

Selenium bietet für so ein Testszenario, mit der sogenannten GRID Architektur, ein gutes Werkzeug. Zum Selenium GRID in einem weiteren Artikel später mehr zu diesem spannenden Thema.

Wie sind Deine Erfahrungen mit der Erstellung eines TestAutomation Frameworks auf Basis von Selenium. Gerne bitte ich Dich Feedback zu geben und Deine Erfahrungen mit uns zu teilen.

Viele Grüße,

Andrés

Quellen

https://code.google.com/p/selenium/wiki/PageObjects

http://www.toolsqa.com/selenium-webdriver/page-object-model/

http://martinfowler.com/bliki/PageObject.html

http://www.it-agile.de/wissen/praktiken/agiles-testen/testgetriebene-entwicklung-tdd/

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.