Page 1

Automatisiertes Webauftritt-Testen auf struktureller und visueller Ebene Bachelorprojekt im Informatikstudium an der Universit채t Basel September 2010

Autor: Reto Kaiser Erlenstrasse 41 4058 Basel Schweiz reto.kaiser@stud.unibas.ch Betreuung: High Performance and Web Computing Departement Informatik Klingelbergstrasse 50 4056 Basel Schweiz Prof. Dr. Helmar Burkhart helmar.burkhart@unibas.ch Dr. Sven Rizzotti sven.rizzotti@unibas.ch


Inhaltsverzeichnis Abstract Einleitung 1. Software-Testen! 1.1 Grundlagen! 1.1.1 Komponententest! 1.1.2 Integrationstest! 1.1.3 Systemtest! 1.1.4 Abnahmetest! 1.1.5 Nicht-funktionale Tests! 1.1.6 Standardisierung! 1.1.7 Interview mit Dr. Franz-Josef Elmer! 1.2 Entwicklungen! 1.3 GUI-Testen!

2 2 3 4 4 5 6 6 7 8 9

2. Webauftritt-Testen! 2.1 Grundlagen! 2.2 Entwicklungen! 2.3 Ansätze! 2.3.1 Komponententest! 2.3.2 Integrationstest! 2.3.3 Systemtest! 2.4 Praxis! 2.4.1 Interview mit Urs Gürtler, Nextron! 2.4.2 Umfrage bei Webauftritt-Betreuern! 2.5 Werkzeuge! 2.5.1 Serverseitige Komponententests! 2.5.2 JavaScript Komponententests! 2.5.3 HTTP Integrationstests! 2.5.4 Browser Integrationstests! 2.5.5 Last Systemtests! 2.5.6 Sicherheit Systemtests!

10 10 11 12 13 14 15 17 17 18 21 21 23 24 25 28 30

3. Webseiten Layout-Testen: Screencompare! 3.1 Problem! 3.1.1 Diversifizierte Client-Landschaft! 3.1.2 Pixelgenaues Design! 3.1.3 Bedarf nach visuellem Layout-Testen! 3.2 Lösungsansatz! 3.3 Funktionsweise! 3.3.1 Testablauf! 3.3.2 Verwendung! 3.3.3 Verfügbarkeit!

31 31 31 32 33 34 35 35 37 42

Zusammenfassung Quellen Abbildungen Literatur


Abstract In der Softwareentwicklung ist das Testen ein zentraler Bestandteil der Qualitätskontrolle. Anhand der Unterteilung Komponenten-, Integrations-, System- und Abnahmetest wird der theoretische Hintergrund und die praktische Anwendung aufgerollt. Moderne Webauftritte und -anwendungen müssen ebenfalls getestet werden, wobei einige Besonderheiten zu beachten sind. Neben der Erläuterung etablierter Ansätze werden einige existierende Werkzeuge anhand von Beispielen vorgestellt. Eine selbstentwickelte Software für visuelle Layout-Tests an Webseiten wird vorgestellt, die gebrauchsfertig und online verfügbar ist.

Einleitung Webauftritte basieren auf einer Reihe von Technologien wie HTTP, HTML, CSS, JavaScript und einigen weiteren. Im letzten Jahrzehnt sind interaktive Webanwendungen entstanden, wobei sich deren Komplexität symbiotisch mit den entsprechenden Technologien entwickelt. Die rasanten Fortschritte in diesem Bereich führen dazu, dass Webanwendungen heute in vielerlei Hinsicht klassischen Anwendungen gleichzustellen sind. Entsprechend angestiegen ist die wirtschaftliche Bedeutung von Webauftritten. Viele sogenannte Dotcom-Firmen bieten ihre Dienstleistungen ausschliesslich über das Internet an. Es gibt also gute Gründe, in die Qualitätskontrolle und damit auch in das Testen von Webauftritten zu investieren. Die Etablierung iterativer und testgetriebener Entwicklungmodelle in den letzten 20 Jahren führte zu einer Erstarkung des automatisierten Testens; ein Konzept, das auch im jungen Bereich des Webauftritt-Testens Anklang findet. Die Client-Server-Struktur von Webauftritten birgt dazu einige strukturelle Stolpersteine. Die verbreiteten Webbrowser sind in der Regel abgeschlossene Endnutzer-Anwendungen, die nur umständlich als Testumgebung genutzt werden können. In dieser Arbeit sollen einige verbreitete Ansätze des Web-Testens vorgestellt, und deren Möglichkeiten und Grenzen ausgelotet werden. Schlussendlich wird die Frage gestellt, wieso und in welchem Umfang es nötig ist, die visuelle Erscheinung einer Webseite automatisiert zu testen. Dazu wird eine Herangehensweise anhand einer Java-Implementierung präsentiert.

-1-


1. Software-Testen 1.1 Grundlagen Unter Software-Testen werden verschiedene Verfahren verstanden, welche zur Sicherstellung der Softwarequalität dienen1 . Mit ihnen wird versucht, Fehler zu finden und neue zu verhindern. Damit ist das Testen ein wichtiger Faktor in der Beurteilung der Produktqualität von Software; speziell die Testabdeckung kann eine aussagekräftige Metrik sein2. Die starke Heterogenität in Softwareentwicklungsprozessen und Laufzeitumgebungen führt zu einem diversifizierten Metier, welches schwer formalisierbar ist. Entwickler, aber auch dedizierte Tester müssen Tests planen, erstellen, durchführen und dokumentieren. IEEE 829-1998 “Software Test Documentation” beschreibt acht Dokumente zur Dokumentation von Tests, welche von der Konzeption, über die Spezifikation von Ein- und Ausgabewerten bis zu einer Zusammenfassung der Ergebnisse reichen. In der Praxis wird, abhängig von den Qualitätsanforderungen, deutlich weniger dokumentiert3. Automatisierte Tests erlauben es häufig, ganz auf eine manuelle Dokumentation zu verzichten, wobei Werkzeuge es ermöglichen aus den Tests selbst berichtartige Dokumente zu erzeugen. Software-Testen beinhaltet sowohl statische wie auch dynamische Techniken. CodeReviews oder -Analysen sind beispielsweise statische Methoden. Diese Arbeit befasst sich hingegen mit den dynamischen Methoden, welche die tatsächliche Ausführung eines Programms oder Programmteils überprüfen. Für die Klassifizierung von Testmethoden, -kriterien oder stufen existieren verschiedenste Modelle. Im Folgenden wird auf einige verbreitete Techniken anhand verschiedener Stufen der Softwareentwicklung im V-Modell4

Abb. 1: Stufen des V-Modells

eingegangen. 1

IEEE 1012-2004, 2004, Abschnitt 5.4.5 IEEE 1012-2004, 2004, Abschnitt 7.8, Tabelle 1 3 Bspw. Interviews, Abschnitt 1.1.7 und 2.4.1 4 Vorgehensmodell der Softwareentwicklung, siehe Abb. 1 -22


1.1.1 Komponententest Mit einem Komponententest (Modultest, Unittest) wird ein einzelner Programmteil auf Fehler geprüft. Eine zu testende Komponente kann beispielsweise ein funktionales Modul im Sinne der Softwarearchitektur oder eine Klasse in der objektorientierten Programmierung sein. Diese Komponente wird isoliert vom Rest der Software getestet. Ist die Funktionalität einer Komponente beschränkt und genau definiert, lassen sich damit auf einfache Weise erwartete Ergebnisse überprüfen. Im einfachsten Fall können die Schnittstellen einer Komponente anhand von Ein- und erwarteten Ausgaben geprüft werden. Dabei werden auch Fehlerszenarien, wie das Verhalten bei ungültigen Eingaben, getestet. Wenn eine Komponente auf weitere Programmteile angewiesen ist, so müssen diese für den Test simuliert werden. In diesem Fall wird von Mock-Objekten gesprochen, welche häufig mit entsprechenden Frameworks für Datenbank- oder Datei-Mocks erstellt werden. Komponententests werden fast immer automatisiert durchgeführt5, wobei entsprechende Werkzeuge, wie die vielzähligen xUnit-Frameworks6, Anwendung finden. Dies ermöglicht es, ein ganzes Set von Komponententests regelmässig auszuführen. Bei genügend grosser Testabdeckung können Entwickler so in Erfahrung bringen, ob eine Softwareänderung neue Fehler auslöst oder alte tilgt. In grösseren Entwicklungsteams kann es sinnvoll sein, die Ausführung und das Bestehen der Komponententests als Bedingung für die Aufnahme neuen Codes zu definieren. Die Testausführung kann beispielsweise von einem Pre-commit hook7 des Versionierungssystems, oder auch vom Erstellungsprozess (Build) ausgelöst werden8 . Ein JUnit 3 Komponententest: public class CalcTest extends TestCase { ! ! ! !

public void testAdd() { ! int result = MyCalc.add(3, 4); ! assertEquals(7, result); }

}

5

Runeson, 2006 http://www.martinfowler.com/bliki/Xunit.html [23.9.2010] 7 Automatisierte Programmausführung vor dem Einchecken in ein Versionierungssystem 8 http://martinfowler.com/articles/continuousIntegration.html#MakeYourBuildSelf-testing [7.9.2010] -36


1.1.2 Integrationstest Das Ziel eines Integrationstests ist es, die vorher durch Komponententests geprüften Programmteile kombiniert zu testen. Dabei können funktionale (Schnittstellen-) Anforderungen, aber auch das Performanzverhalten Testobjekte sein. Die einzelnen Komponenten werden dabei als Black Boxes9 gehandhabt. Wissen über deren interne Funktionsweise und Struktur ist für den Integrationstest also nicht nötig. Auch hier sollten sowohl gültige wie auch fehlerhafte Zwischenkomponenten-Interaktionen getestet werden, indem eine Komponente eine oder mehrere andere verwendet. Um den Testaufwand überschaubar zu halten, macht es bei grösseren Projekten Sinn, nicht alle Komponenten in jeglichen Kombinationen gegeneinander zu testen. Statt dessen können gemeinsam geprüfte Programmteile in einem nächsten Schritt als einzelne Komponente verstanden werden, welche in Zusammenarbeit mit einer anderen zusammengesetzten Komponente getestet wird. Dieses stufenweise, n-äre Zusammensetzen der Software wird als Bottom Up10-Ansatz bezeichnet. Häufig werden aber auch Mischformen mit Ansätzen wie Top Down 11 (umgekehrte Zusammenbaureihenfolge) oder Big Bang12 (Zusammenarbeit der Komponenten im Gesamtprodukt testen) verwendet. Bei Projekten mit mehreren Entwicklern wird mit Integrationstests die Zusammenarbeit von Komponenten unterschiedlicher Autoren getestet. Schnittstellenspezifikationen und änderungen werden demnach auf die Probe gestellt. In solchen Entwicklungsszenarien macht es besonders Sinn diese Teststufe zu automatisieren. Integrationstests finden entgegen ihrer akademischen Definition im V-Modell aber auch in Ein-Mann-Projekten ohne jegliche Komponententests Anwendung. Abhängig von der verwendeten Technologiepalette und der eingebauten Testbarkeit wird der Automatisierungsaufwand unvertretbar hoch, sodass das Zusammenwirken der Komponenten in deren Entwicklungsphase vom Autor manuell getestet wird.

1.1.3 Systemtest Beim Systemtest wird der Black Box-Ansatz weitergetrieben, wobei das ganze zusammengesetzte Software-System ohne Wissen über dessen inneren Aufbau getestet wird. Die Testumgebung simuliert dabei die spätere Produktivumgebung.

9

Ohne Kenntnisse über die innere Funktionsweise, es werden nur öffentliche Schnittstellen betrachtet. BS 7925-1 11 BS 7925-1 12 BS 7925-1 -410


In diesem Schritt testet die entwickelnde Organisation erneut die Funktionalität der Software, aber auch die Erfüllung nicht-funktionaler Anforderungen. Solche Anforderungen an Performanzverhalten, Sicherheitsvorkehrungen oder Gebrauchstauglichkeit müssen genau spezifiziert sein; ein späterer Abschnitt befasst sich mit derem Spezifizieren und Testen. Das Automatisieren von Systemtests kann sich als schwierig, beziehungsweise unwirtschaftlich erweisen13 , speziell wenn diese mehrheitlich aus BenutzerschnittstellenTests bestehen. Eine spätere formelle Abnahme der Software durch den Kunden kann vereinfacht werden, indem die Systemtest-Abläufe und -Ergebnisse genau dokumentiert werden, um sie dem Kunden zu präsentieren.

1.1.4 Abnahmetest Ein Abnahmetest (Acceptance test und User acceptance test) findet bei praktisch jedem für einen Kunden entwickelten System statt, Umfang und Formalitätsgrad varieren jedoch stark. IEEE 1012-2004 “Software Verification and Validation” definiert den Vorgang als “Formal testing conducted to determine whether or not a system satisfies its acceptance criteria and to enable the customer to determine whether or not to accept the system.” 14 In diesem Sinne wird im englischen Sprachgebrauch vielfach zwischen Acceptance testing und User acceptance testing unterschieden, wobei ersteres durch den Entwickler, und zweiteres durch den Kunden oder Anwender durchgeführt wird. Ein User acceptance Test dient meist als Abnahmekriterium für eine Software. Dabei soll die Funktionalität des Produkt mit realen Anwendungsszenarien überprüft werden, wobei vielfach angestrebt wird, von der Entwicklung unabhängige Tester einzusetzen. Systemtest-Dokumentationen können zur Abnahme-Beurteilung hinzugezogen werden. Sogenannte Benutzergeschichten (User Story), welche in grösserem Aussmass auch in agilen, testgetriebenen Entwicklungsmodellen Anwendung finden, können Anforderungen für Abnahmetests sein. Weniger detailliert als Anwendungsfälle (Use Case), dafür ein ausführlicheres Benutzerszenario beschreibend, dienen sie der abstrakten Beschreibung der Software-Anforderungen durch den Kunden. Eine Benutzergeschichte: Beim öffnen eines Videos wird dieses an der zuletzt gestoppten Position oder, wenn noch nie geöffnet, an dessen Anfang abgespielt.

13 14

Hoffman, 1999 IEEE 1012-2004, 2004, Abschnitt 3.1.1 -5-


1.1.5 Nicht-funktionale Tests Aus Anwendungsfällen, oder daraus abgeleitet, können die funktionalen Anforderungen einer Software definiert werden. Sie beschreiben, was diese tun soll, wie sie also Eingaben verarbeitet, und welche Ausgaben erwartet werden. Im Gegensatz dazu definieren die nicht-funktionalen Anforderungen, wie sich das System in allen anderen Belangen verhält. Diese Qualitätsauflagen können verschiedenste Bereiche tangieren: Performanz, Sicherheit, Gebrauchstauglichkeit (Usability), Wartung, Robustheit, Erweiterbarkeit, Installation, Skalierbarkeit, Lokalisierbarkeit, Dokumentation et cetera15. Abhängig von Umfang, gesetzlichen Rahmenbedingungen, Einsatzgebiet und so weiter einer Software, fallen diese Nebenbedingungen unterschiedlich grosszügig aus. Einige dieser Anforderungen können im Sinne der Informatik und Informationstechnik getestet werden, benötigen aber meist spezialisierte Kenntnisse ausserhalb der Softwareentwicklung. Der vielfältige Bereich des Performanzverhaltens, welcher sich zum Beispiel mit der Skalierbarkeit, dem Zeitverhalten und der Verfügbarkeit eines Systems befasst, kann Kenntnisse zu Netzwerktopologie, Last-Erzeugung und Hardware-Verhalten voraussetzen. Um hingegen die Gebrauchstauglichkeit einer Software einzuschätzen, sind Psychologie-Kenntnisse, Design-Leitfäden oder spezielle Gerätschaften nötig. Diese diversifizierten Qualifikationsanforderungen führen zu einem hohen Aufwand des Testens und Erfüllens von nicht-funktionalen Anforderungen. Es wird deshalb vorgeschlagen, die Wichtigkeit dieser Anforderungen für den Kunden in Erfahrung zu bringen.16 Nicht-funktionale Tests werden üblicherweise in der Integrations- oder Abnahmephase des Projekts durchgeführt, wobei eine vielfältige Palette an freien, sowie kommerziellen Werkzeugen und Diensten verwendet werden kann.

1.1.6 Standardisierung Das Ausmass und die Professionalität des Software-Testens hat sich in den letzten 30 Jahren massiv gesteigert.17 Viele Softwareschmieden besitzen unterdessen Personal für das Testen und dessen Leitung. Während eine Vielfältigkeit an Meinungen und Praktiken zum Software-Testen existiert, versuchen einige Organisationen Begriffsdefinitionen, Anforderungen und Abläufe zu standardisieren. Im folgenden einige aktuell gültige Standardisierungsdokumente zum

15

Bspw. Chung; Leite, 2009 Melnik; Meszaros, 2009, Abschnitt 5.2.2 17 Gelperin; Hetzel, 1988, Abschnitt “Growth of professionalism” -616


Thema, sowie ein mir vielversprechend erscheinender Entwurf für einen umfassenden ISO/IEC-Standard: • IEEE 829-1998. Software Test Documentation • IEEE 1008-1987. Software Unit Testing • IEEE 1012-2004. Software Verification and Validation • IEEE 1028-2008. Software Reviews and Audits • ISO/IEC 25000:2005. Software product Quality Requirements and Evaluation (SQuaRE) • ISO/IEC 29119. Software Testing (Entwurf, siehe http://softwaretestingstandard.org)

1.1.7 Interview mit Dr. Franz-Josef Elmer Dr. Franz-Josef Elmer unterrichtet “Software Engineering” an der Universität Basel und arbeitet seit 1998 in der Softwareentwicklung. Er entwickelte in zwei- bis sechsköpfigen Teams GUI- und Webanwendungen mit Client-Server-Struktur, wobei vor allem Java, Bash, Python, SQL, XML und HTML Anwendung finden. Wie testen Sie heute Anwendungen? Elmer: »Wir betreiben Unit-, Integrations- und Systemtests, wobei die Unittestabdeckung weit unter 100% liegt, wahrscheinlich auch unterhalb von 50%. Meist gehen wir nach dem Prinzip “Code a little, test a little” vor. Geschriebener Code muss also testbar sein, wobei die entsprechenden Tests nach der Fertigstellung einer Etappe umgesetzt werden. Reine testgetriebene Entwicklung ist bei uns kein Thema. Ich kann mir speziell in der explorativen Anfangsphase der Entwicklung einer Software auch schlecht vorstellen, wie das sinnvoll funktionieren soll.« Welche Entwicklungen konnten und können Sie beobachten? »In meiner Anfangsphase haben wir das gemacht, was man heute manuelle System- und Abnahmetests nennt, die Anwendung also einfach ausprobiert. In dieser Zeit wurden meist wasserfallartige Entwicklungsmodelle verwendet. Vor 10 Jahren bin ich zum ersten Mal auf das Konzept des automatischen Testens gestossen. Nachdem ich selber ein Framework entwickelt

»Vor 10 Jahren bin ich zum ersten Mal auf das Konzept des automatischen Testens gestossen.«

habe, hat mich ein Kollege auf einen Artikel in der iX über JUnit, einem Testingframework, aufmerksam gemacht.

-7-


Automatisiertes Testen hat sich in der Zwischenzeit entwickelt und ist in der Softwareentwicklung zum Standard geworden. Der Trend zu iterativen Entwicklungsmethoden hat dazu beigetragen.« Welche Herausforderungen sehen Sie beim Webauftritt-Testen? »Serverseitig ist das sicher unproblematisch, Unittests für die Logik sind da stabil. Um die Clientlogik gut testen zu können sind aber die Controller [im MVC-Pattern] zu sehr mit den GUI-Elementen verbunden. GUI-Tests sind generell heikel und brechen bereits bei kleinen Änderungen. Komplexe Benutzerschnittstellen und dadurch viele Eingabemöglichkeiten bringen einen hohen Testaufwand mit sich, wobei der Nutzen vielfach unklar bleibt.«

1.2 Entwicklungen Die Koryphäen des Software-Testens Dave Gelperin und William C. Hetzel beschreiben18 1988 folgende fünf Phasen des frühen Testens von Software: • Bis 1956 “Debugging oriented”: Fehler werden explorativ gefunden und behoben. • 1957-1978 “Demonstration oriented”: Wachsende wirtschaftliche Wichtigkeit von Software führt zu stärkerem Engagement für das Fehlerfinden. • 1979-1982 “Destruction oriented”: Testen soll aktiv Fehler finden, es müssen also auch unübliche Eingaben berücksichtigt werden. • 1983-1987 “Evaluation oriented”: Softwarequalität wird anhand von Richtlinien evaluiert. • 1988 “Prevention oriented”: Anforderungen werden im Voraus definiert, Tests zu deren Überprüfung werden geplant. Das Aufkommen der “Prevention oriented”-Periode hat sich wohl bewahrheitet, in der Zwischenzeit hat sich jedoch wiederum einiges getan. In den 90er-Jahren wird das Software-Testen professionalisiert, wobei das Thema im grossen Stil diskutiert wird, beispielsweise an Konferenzen wie der “Software Testing Analysis & Review” (STAR, seit 1992 19) oder der “Software & Systems Quality” (SQC, seit 199620). Ausserdem wird 199121 erstmals der Standard ISO/IEC 9126 “Software engineering - Product quality” veröffentlicht.

18

Gelperin; Hetzel, 1988, Abschnitt “Evolution of the models” http://www.sqe.com/Events/Archive/sw2002/ [7.9.2010] 20 http://www.iqnite-conferences.com [7.9.2010] 21 http://www.iso.org/iso/iso_catalogue/catalogue_ics/catalogue_detail_ics.htm?csnumber=16722 [7.9.2010] -819


Gleichzeitig entstehen testgetrieben sowie agile Entwicklungsmethoden wie Scrum 22 oder Extreme Programming23, bei welchen das Testen ein wichtiger Bestandteil des Entwicklungsprozesses ist. Speziell das Komponententesten, welches es dem Softwareautor ermöglicht, leicht automatierbare Tests für funktionale Anforderungen zu erstellen, gewinnt dadurch an Bedeutung. 1998 begründet und beschreibt der Zürcher Erich Gamma zusammen mit dem Amerikaner Kent Beck das beliebte JUnit24. Das Software-Testen hat also einige Paradigmenwechsel durchgemacht, und wird sich auch zukünftig an neue Ansprüche und Technologien anpassen müssen.

1.3 GUI-Testen Als Computerprogramme noch mehrheitlich mit einer Kommandozeile (CLI) gesteuert wurden, beschränkte sich die Benutzerschnittstelle auf eingegebenen Text und die textuelle Ausgabe. Das Testen einer solchen Benutzerschnittstelle ist relativ überschaubar, da die Anzahl an Eingabemöglichkeiten beschränkt werden kann. Im Zeitalter von grafischen Benutzeroberflächen (Graphical user interface, GUI) hingegen, ist das Testen der Benutzerschnittstelle einiges problematischer. Eine GUI besitzt typischerweise eine Vielzahl von Steuerelementen wie Schaltflächen, Bildlaufleisten, Menüs et cetera, welche gleichzeitig Eingaben entgegennehmen können. Durch die grosse Anzahl solcher Elemente und die vielen möglichen Eingabe-Reihenfolgen ergibt sich schnell eine unüberschaubar grosse Anzahl von GUI-Zuständen. Aufgrund dieser problematischen Umstände ist es schwierig eine GUI durchgängig zu testen, und es wird nötig das Testen zu automatisieren. In der Praxis werden häufig manuelle Benutzerinteraktionsabläufe aufgezeichnet, um sie dann mit einer entsprechenden Software automatisiert abspielen zu können. Dadurch wird der manuelle Aufwand auf das Aufzeichnen reduziert, und der Test kann beliebig oft wiederholt werden. Um eine GUI überhaupt automatisiert testbar zu machen, müssen Benutzerinteraktionen automatisierbar sein. Einige Ansätze führen

Abb. 2: GUI-Testpläne für MS WordPad

22

Takeuchi; Nonaka, 1986 Beck, 1999 24 Gamma; Beck, 1999 23

-9-


Benutzereingaben auf Betriebssystemebene aus25, sodass keine speziellen Vorkehrungen im zu testenden Programm vorgenommen werden müssen. Andernfalls kann ein GUITreiber in das Programm verbaut werden, über welchen ein anderes Programm die zu testende GUI mit Eingaben versorgen, und Ausgaben auslesen kann. Auch das Überprüfen der Ausgaben einer GUI mit einem automatisierten Test ist problematisch. Grafische Ausgaben können abhängig von der Laufzeitumgebung in Dimensionen, Farben und Schriftarten variieren. Eine automatische Validierung erkennt solche Unterschiede als Fehler, obwohl sie unter Umständen gewollt sind.

2. Webauftritt-Testen 2.1 Grundlagen Grössere Webauftritte (Website) sind heute üblicherweise sogenannte Webanwendungen, also Computerprogramme, die auf einem Webserver laufen. Grundsätzlich dient dabei der Webclient des Anwenders als Thin Client, wobei die eigentliche Programmlogik als CGI26-Programm, oder als integrierte Anwendung des Webservers auf einem entfernten Rechner ausgeführt wird.

Abb. 3: Datenfluss einer Webanwendung

Server und Client kommunizieren dabei mit dem Hypertext-Übertragungsprotokoll (HTTP) über eine Netzwerkverbindung, sodass im Idealfall eine fast verzögerungsfreie Benutzerschnittstelle bereitgestellt werden kann. Diese Architektur bedingt im Vergleich mit einer klassischen, lokal laufenden Software einige technische Unterschiede. Einerseits wird durch den Thin Client die Installation, Konfiguration und Wartung für den Anwender grössenteils hinfällig, und der Hersteller kann Softwareänderungen unverzögert zur Verfügung stellen, andererseits entsteht

25 26

Z.B. “AutoHotkey” Common Gateway Interface, RFC 3875 - 10 -


serverseitig ein Single Point of Failure (SPOF), und es muss damit gerechnet werden, dass die Client-Server-Verbindung jederzeit unterbrochen werden kann. Diese Eigenheiten müssen bei der Qualitätsbeurteilung von Webanwendungen berücksichtigt werden. Im Webbereich kommen einige spezialisierte Techniken zum Einsatz, die unter Anderem ein angenehmes Benutzererlebnis ermöglichen: • Cookies ermöglichen es, auf dem zustandslosen Protokoll (HTTP) Benutzer über mehrere Anfragen hinweg zu identifizieren. • Hypertext-Auszeichnungssprache (HTML) strukturiert als Grundlage jeder Webseite Inhalte wie Text, Bilder und Hyperlinks, welche im Webbrowser angezeigt werden. • Cascading Style Sheets (CSS) dient der Definition der Darstellung von Benutzerschnittstellen-Elementen der HTML, womit der Inhalt einer Webseite von dessen Aussehen getrennt wird. • JavaScript ist eine Skriptsprache, welche clientseitig als Teil einer Webseite im Webbrowser ausgeführt wird und HTML-Elemente, sowie CSS-Regeln ändern kann. Damit werden dynamische Benutzerschnittstellen innerhalb einer Webseite möglich. Zur Auseinandersetzung des Testens solcher Anwendungen ist festzuhalten, dass erstens die Programmlogik lose gekoppelt auf zwei physisch getrennten und technisch verschiedenen Systemen (Client und Server) abläuft, und sich zweitens speziell die Ausprägungen nicht-funktionaler Anforderungen erheblich von denen klassischer Software unterscheiden können.

2.2 Entwicklungen Die Disziplin des Webauftritt-Testens ist relativ jung. Grund dafür ist, dass Webanwendungen erst in den letzten zwei Jahrzehnten entstanden sind, wobei ihr Komplexitätsgrad in den letzten Jahren erheblich zugenommen hat. Eine der ersten Webanwendungen ist “SPIRES HEP” der Stanford-Universität, welche es 1991 erlaubt, einen Katalog von TeilchenphysikPublikationen zu

Abb. 4: SPIRES HEP Benutzerschnittstelle, 1991

durchsuchen27 . 27

http://www.slac.stanford.edu/history/earlyweb/firstpages.shtml [7.9.2010] - 11 -


Technologische Meilensteine sind CGI (1995 28), PHP (1995 29), JavaScipt (199530), XMLHttpRequest (1999 31) und Ajax (200532). Während der New Economy 33 der 1990er Jahre entstehen grosse Webanwendungen34, welche schnell an Interaktionsmöglichkeiten gewinnen, indem asynchrone Kommunikation zwischen Client und Server (Ajax), eingesetzt wird. Damit kann die Benutzerschnittstelle im Webbrowser zügig und nahtlos auf Benutzereingaben reagieren, indem die auf dem Server laufende Anwendung im Hintergrund mit JavaScript kontaktiert wird. Software fürs Webauftritt-Testen entsteht in dieser Ära. So publiziert Russell Gold im Jahr 200035 die Version 1.0 von HttpUnit, welche es erlaubt Komponententests für Webseitenaufrufe zu schreiben, ohne einen Webbrowser einsetzen zu müssen. Um die Jahrtausendwende gibt es also Bestrebungen, die Funktionalität von Webauftritten zu überprüfen36 , namentlich den Kontrollfluss von Forms und Hyperlinks. Aber auch das Überprüfen nicht-funktionaler Anforderungen wie der Gebrauchstauglichkeit37 wird thematisiert. Die wachsende wirtschaftliche Bedeutung während den letzten zehn Jahren von Webanwendungen wie Google, Yahoo, Facebook und Co. hat dazu geführt, dass mehr Ressourcen in die Qualitätskontrolle von Webanwendungen investiert werden. Die Disziplin des Webauftritt-Testens ist jung, und die Anwendungsfälle gehen stark auseinander.

2.3 Ansätze Es scheint sich bis heute kein Konsens gebildet zu haben, wie ein Webauftritt getestet werden soll. Standardisierungsdokumente geben, durch ihre Langlebigkeit bedingt, wenig Auskunft. Verschiedenste Anforderungskataloge und technische Umsetzungen führen zu einer Vielzahl möglicher Ansätze.

28

http://www.w3.org/Daemon/User/CGI/Overview.html [7.9.2010] http://groups.google.ch/group/comp.infosystems.www.authoring.cgi/msg/cc7d43454d64d133 [7.9.2010] 30 http://web.archive.org/web/20070916144913/http://wp.netscape.com/newsref/pr/newsrelease67.html [7.9.2010] 31 http://blogs.msdn.com/b/ie/archive/2006/01/23/516393.aspx [7.9.2010] 32 http://www.adaptivepath.com/ideas/essays/archives/000385.php [7.9.2010] 33 Dienstleistungsbetonte Wirtschaftsform, geprägt durch Globalisierung und Digitalisierung 34 Bspw. Google 1998, Hotmail 1996, Yahoo 1995 35 http://sourceforge.net/mailarchive/message.php?msg_name=v03110704b5d5d324518e %40%5B207.106.60.98%5D [7.9.2010] 36 Yang; Huang; Wang, 1998 37 Corry; Frick; Hansen, 1997 - 12 29


2.3.1 Komponententest Die eigentliche Anwendungslogik einer Webapplikation, die auf einem Server läuft, kann grösstenteils im Sinne der klassischen Softwareentwicklung betrachtet werden. Um sie testbar zu machen, sollte sie streng von der Benutzerschnittstelle getrennt sein. Dazu hat sich mehrheitlich das Model View Controller (MVC)Paradigma etabliert. Dabei werden Anwendungslogik (Model), Präsentation (View) und Programmsteuerung (Controller) als möglichst unabhängige Einheiten betrachtet, welche über Schnittstellen kommunizieren. Gängige Webanwendungs-Frameworks wie das Zend Framework, Catalyst oder JavaServer Faces erlauben oder fordern die Entwicklung im MVC-Stil. In einem MVC-Projekt können die üblichen Komponententest-Frameworks für die entsprechende Programmiersprache verwendet werden, während Mock-Objekte die Datenquellen simulieren. Abb. 5: MVC-Paradigma Die serverseitige Anwendungslogik ist aber nicht die einzige Stelle, an der Komponententests angewendet werden. Durch die zunehmenden Interaktionsmöglichkeiten von Web-Benutzerschnittstellen, wird vermehrt Programmlogik auf der Clientseite gebräuchlich. So lädt beispielsweise eine Facebook-Webseite um die 600KB komprimierten JavaScript-Quellcode nach38 . Beliebte JavaScript-Bibliotheken haben in ihren aktuellen Versionen erheblichen Umfang: jQuery 6240 Zeilen39 , MooTools 4329 Zeilen40 und Dojo 11251 Zeilen41 Code. Dieser Teil einer Webanwendung wird nur selten automatisiert getestet. Der häufig prozedurale Programmierstil von JavaScript-Code und die enge Verknüpfung von Logik und Benutzerschnittstelle verringern die Testbarkeit. Gleichzeitig sind Webbrowser als wichtigste JavaScript-Interpreter nicht dafür ausgelegt, automatisierte Tests laufen zu lassen. Trotzdem gibt es Bestrebungen, JavaScript-Komponententests auf verschiedenen Ebenen möglich zu machen. Eine Variante ist es, die Anwendungslogik in einem Webbrowser zu 38

http://www.facebook.com [7.9.2010] http://code.jquery.com/jquery-1.4.2.js [7.9.2010] 40 http://mootools.net/download/get/mootools-1.2.4-core-nc.js [7.9.2010] 41 http://download.dojotoolkit.org/release-1.5.0/dojo.js.uncompressed.js [7.9.2010] - 13 39


testen. Da sich die JavaScript-Interpreter der verschiedenen Webbrowser teilweise erheblich unterscheiden, können dabei auch Interpreter-implementierungsspezifische Fehler aufgedeckt werden. Die Test-Frameworks sind dabei selbst in JavaScript geschrieben und bieten an die xUnit-Familie angelehnte Funktionalität. Andere Ansätze führen die zu testende Logik in einem besser kontrollierbaren, dezidierten JavaScript-Interpreter ausserhalb eines Webbrowsers aus. So verwenden einige TestFrameworks Mozillas in Java geschriebene JavaScript-Implementierung Rhino42. Während die Benutzerschnittstelle einer Webanwendung als wie komplexer wird, muss häufig festgestellt werden, dass ein Grossteil der serverseitigen Anwendungslogik clientseitig in JavaScript dupliziert wird. Das führt zu doppeltem Wartungs- und Testaufwand. Einige Webanwendungs-Frameworks versuchen diesen Missstand zu beheben, indem Quellcode in einer einzigen Programmiersprache beim Deployment in die entsprechenden Technologien der Clientseite wie HTML, CSS und JavaScript übersetzt wird. Wichtige Vertreter sind Google Web Toolkit (GWT)43 in Java, RubyJS 44 in Ruby und Wt45 in C++. Bei Verwendung eines solchen Frameworks können auch Client-Komponententests in der Wirtssprache geschrieben werden, welche entweder im Wirtssprachen- oder JavaScriptInterpreter laufen können46 .

2.3.2 Integrationstest Integrationstests an Webanwendungen werden grösstenteils mit zwei verschiedenen Ansätzen auf unterschiedlichen Ebenen der Software umgesetzt. Dabei soll festgestellt werden, ob die möglicherweise vorher komponentengetesteten Programmteile auch als Ganzes ihre Funktionalität erfüllen. Um die reine Programmlogik auf dem Server zu testen, können HTTP-Anfragen simuliert und Antworten ausgewertet werden. Ein entsprechendes Testing-Framework mimt den Browser eines Anwenders und erlaubt dadurch, die Client-Server-Kommunikation zu überprüfen. Dazu müssen entsprechende Anfragen formuliert und, etwas aufwändiger, die meist als HTML-Dokumente vorliegenden Antworten auf ihre strukturelle Korrektheit überprüft werden. 42

http://www.mozilla.org/rhino/ [7.9.2010] http://code.google.com/webtoolkit/ [7.9.2010] 44 http://rubyforge.org/projects/rubyjs/ [7.9.2010] 45 http://www.webtoolkit.eu [7.9.2010] 46 http://google-web-toolkit.googlecode.com/svn/javadoc/1.5/com/google/gwt/junit/client/GWTTestCase.html [7.9.2010] - 14 43


Um die Clientseite einer Webanwendung testen zu können, muss zudem das Verhalten des Browsers testbar sein. Dazu müssen externe Ressourcen eines HTML-Dokuments wie CSS-Dateien, Bilder und JavaScript-Programme nachgeladen, die CSS-Regeln auf die HTML-Elemente angewendet, und JavaScript ausgeführt werden. Diese Funktionalität steckt in bestehenden Endanwender-Browsern, welche tatsächlich für Integrationstests verwendet werden. Dabei muss der verwendete Browser von einer programmierbaren Umgebung ferngesteuert werden. Es existieren weitere Ansätze, in denen das Verhalten eines Browsers simuliert wird, die Webseiten also nicht tatsächlich gerendert werden, ihr gesamtes Verhalten aber im Hintergrund abläuft und über entsprechende Schnittstellen testbar ist.

2.3.3 Systemtest Auf der Systemtest-Ebene werden Webauftritte meist auf nicht-funktionale Anforderungen geprüft. So kann es nötig sein eine neue Version einer Webanwendung vor ihrer Aufschaltung in einer fast-produktiven Umgebung einem letzten Lasttest zu unterziehen, um sicherzugehen, dass der Produktstart reibungslos über die Bühne geht. Eine Vielzahl weiterer Anforderungen wird in einem live-ähnlichen oder tatsächlich produktiven Setup getestet: • Sicherheit: Webanwendungen werden häufig ganz gezielt angegriffen, um diese unbenutzbar zu machen oder Informationen zu stehlen. Verbreitete Angriffsvektoren sind SQL-Injection und Cross-Site Scripting (XSS)47. Neben den Vorkehrungen die während der Sotwareentwicklung getroffen werden sollten, um solche Lücken zu verhindern, gibt es Analye- und Scanning-Werkzeuge, mit welchen Sicherheitslücken in existierenden Anwendungen gefunden werden können. So können mittels Fuzzing48 Fehler gefunden werden, die bei unvorhergesehenen Eingaben auftreten, indem zufällige Eingaben an HTTP- und HTML-Schnittstellen gesendet werden. Mit Penetrationstests49 werden mögliche Sicherheitslücken systematisch ausprobiert, um beispielsweise SQL-Injection-Lücken zu finden. Dies kann manuell, aber auch unterstützt durch grösstenteils automatisierte Werkzeuge geschehen, welche zum Beispiel für einen bestimmten HTTP-POST-Parameter übliche SQL-Injection-Werte übergeben.

47

http://www.owasp.org/index.php/OWASP_Top_Ten_Project [7.9.2010] Bspw. Neystadt, 2008 49 Bspw. Wack; Tracy; Souppaya, 2003 - 15 48


• Gebrauchstauglichkeit: Webanwendungen stehen heute vielfach unter hohem Konkurrenzdruck. Damit Benutzer einem Webauftritt loyal bleiben, muss dessen Bedienung effizient und zufriedenstellend sein. Um dies zu erreichen, ist es nötig, das Benutzerverhalten zu kennen, und die eigenen Webseiten entsprechend anzupassen. Ein ganzes Berufsfeld widmet sich der Thematik, wie Menschen vor einem Computerbildschirm eine Webseite aufnehmen und mit ihr interagieren. Dabei müssen Softwareentwickler, Designer und Usability-Experten zusammenarbeiten. Die Analyse der Gebrauchstauglichkeit ist vornehmlich ein manueller Vorgang. Doch es gibt auch Möglichkeiten, die Wirkung eines Weblayouts auf einen Probanden mit Gerätschaften maschinell zu erfassen. Alternativ können die Interaktionsflüsse auf einem Webauftritt gemessen werden, woraus die Wichtigkeit von Hyperlinks, Forms und Knöpfen bestimmt werden kann. Wenn gleichzeitig unterschiedlichen Benutzergruppen verschiedene Benutzeroberflächen-Versionen präsentiert werden (A-B-Test50), können die Auswirkungen von Layout-Änderungen statistisch gemessen werden. • Performanzverhalten: Ein verbreitetes Problem von Webanwendungen ist die Überlastung der Serverressourcen bei einem Anstieg der Anfragemenge. Architekturbedingt ist ein Webauftritt im Normalfall der beliebigen Anzahl von Clientanfragen ausgeliefert. Plötzlicher oder allmählicher Popularitätsanstieg kann eine Webanwendung lahmlegen. Es ist nicht einfach, Anforderungen an die verarbeitbare Anfragemenge und an die Verfügbarkeit einer Serverinfrastruktur zu formulieren. So gehen auch grosse Webauftritte hin und wieder aufgrund einer Vielzahl von Zugriffen in die Knie. Gleichzeitig ist es schwierig die Anforderungen gründlich zu testen, und auch eine Skalierungs-Strategie bereit zu halten. Bei sogenannten Lasttests (Stress test)51 wird eine grosse Zahl von HTTP-Anfragen an den Webserver geschickt, wobei dessen Performanzverhalten und allfällige Flaschenhälse studiert werden können. Dabei muss allerdings beachtet werden, dass das tatsächliche Verhalten erwarteter Benutzer simuliert wird. Es sollten also reale Navigationsflüsse durchgeführt werden, mitsamt Logins, Form-Absendungen et cetera.

50 51

Bswp. Dixon; Enos; Brodmerkle, 2006 BS 7925-1 - 16 -


Weitere nicht-funktionale Anforderungen an Webauftritte wie Barrierefreiheit, Lokalisierbarkeit oder Interoperabilität52 werden teilweise getestet, setzen aber meist auch Kenntnisse ausserhalb des IT-Bereichs voraus, und erfordern viel manuellen Testaufwand.

2.4 Praxis Die Webentwicklung ist ein vielfältig bepflügtes Feld. Webauftritte werden von Einzelpersonen im Wohnzimmer realisiert, während grosse Firmen gleichzeitig ContentManagement-Systeme (CMS) entwickeln und damit Millionenumsätze generieren53 . Entsprechend heterogen sind Ansätze und Umfänglichkeiten von Webauftritt-Tests in der Praxis.

2.4.1 Interview mit Urs Gürtler, Nextron Urs Gürtler arbeitet seit zweieinhalb Jahren als Applikationsentwickler bei der “Nextron Internet Team GmbH”54. Diese beschäftigt acht Mitarbeitende und erstellt seit 1996 Webauftritte wie www.mybasel.ch oder www.biovalley.ch. Wie realisiert ihr eure Projekte normalerweise? Gürtler: »Wir verwenden unser eigenes CMS, welches mit ColdFusion umgesetzt ist. Dieses wird für jeden Webauftritt entsprechend angepasst und nach Bedarf mit Modulen ergänzt. Üblicherweise beschäftigen sich zwei Personen einige Arbeitstage mit einem Projekt.« Wie testet ihr eure Software? »Unser CMS wird während der iterativen Entwicklung manuell getestet. Dafür wird etwa 30% der Entwicklungszeit aufgewendet. Automatisierte Tests haben wir keine. An den fertigen Webauftritten werden je nach Kundenansprüchen manuelle Systemtests durchgeführt, um Anforderungen wie Sicherheit, Skalierbarkeit und Funktionalität zu prüfen.« Wird das Webseiten-Layout getestet? »Der Designer, welcher die Templates für das CMS erstellt, testet die korrekte Darstellung der Webseiten manuell in verschiedenen Browsern auf unterschiedlichen Betriebssystemen.«

52

Bspw. Chung; Leite, 2009 http://www.day.com/day/en/company.html [7.9.2010] 54 http://www.nextron.ch [7.9.2010] - 17 53


Welche Entwicklungen können Sie beobachten? »Die Ansprüche unserer Kunden steigen, die Webauftritte werden als wie komplexer. Die meisten wollen irgendetwas Aussergewöhnliches auf ihrer Website.«

2.4.2 Umfrage bei Webauftritt-Betreuern Folgende vier Fragestellungen habe ich an Webauftritt-Betreuer geschickt, um einschätzen zu können, in welchem Umfang deren Webseiten getestet werden: • UI Tests: Wird die korrekte visuelle Darstellung Ihrer Webseite auf unterschiedlichen Endnutzersystemen (Browsern, Geräten, Einstellungen) getestet? • Automatisierung: Wenn ja, geschieht dies automatisiert durch Software (welche)? • Andere Tests: Werden andere Aspekte Ihrer Webseite getestet? • Automatisierung: Wenn ja, geschieht dies automatisiert (Serverseitige Unit Tests, Clientseitige Unit Tests, Integrations Tests, …)? • Anzahl Webentwickler: Wie viele Personen sind für die Entwicklung und Wartung Ihrer Webseite verantwortlich?

Von 242 Anfragen sind 35 Antworten zurückgekommen. Herzlichen Dank an alle beteiligten Personen der folgenden Webauftritte und Firmen!: www.cmsbox.com, www.maxomedia.ch, www.iwannagothere.com, www.homegate.ch, www.amazee.com, www.birdlife-zuerich.ch, www.dropbox.com, www.20minuten.ch, www.zdf.de, www.skyscanner.net, www.ford.com, www.ubs.com, www.hilti.com, www.comparis.ch, www.netcetera.ch, www.search.ch, www.autoscout24.ch, www.post.ch, www.zhaw.ch, www.idg.ch, www.zeeyoo.com, www.hsr.ch, www.bambuser.com, www.jinni.com, www.swisscom.com, www.bakespace.com, www.comvation.com, www.mubi.com, www.liip.ch, www.weltwoche.ch, www.xwave.ch, www.cookstr.com, www.bs.ch, www.rtpartner.ch, www.pornhub.com und www.tokenrock.com. Grösse der Entwicklerteams 79% der Befragten geben an, ein Entwicklerteam mit ein bis zehn Mitarbeitenden zu beschäftigen.

- 18 -


Anzahl Webentwickler

1-5

6-10

11-20 21-50 51-100

Praktisch alle Befragten testen ihren Webauftritt auf die eine oder andere Art, und überprüfen auch die korrekte Darstellung der Benutzerschnittstelle auf verschiedenen Endnutzersystemen. Testautomatisierung Eine Mehrheit setzt an irgendeiner Stelle auf Testautomatisierung. Automatische Benutzerschnittstellen-Tests verwenden hingegen nur 12% der Entwicklerteams, welche allesamt aus 10 oder mehr Entwicklern bestehen. UI Tests

Andere Tests

Automatisiert 12 %

Manuell 88 %

Automatisiert 63 %

Manuell 37 %

Einige Entwicklerteams führen Komponententests am serverseitigen Quellcode durch. Eine ähnlich grosse Menge führt automatisierte Systemtests durch, meist um nichtfunktionale Anforderungen wie die Ladezeit oder Barrierefreiheit zu prüfen. Getestete Entwicklungsstufen

9 4 Komponententests

Integrationstests

7 Systemtests

Bei den automatisiert getesteten Anforderungen überwiegen die funktionalen knapp den nicht-funktionalen. Eine leichte Mehrheit wird serverseitig getestet.

- 19 -


Getestete Anforderungen

11

Testausführung

10

8

7 Funktional Nicht-funktional

Serverseitig

Clientseitig

Verwendete Software Zur Testautomatisierung werden folgende Software-Lösungen genannt: Selenium55 (4x), Grinder56, Google Website Optimizer57 , JUnit58, NUnit59, HP SiteScope60, HP LoadRunner61, Webtrends62 , WebAii63, IBM Rational64 und Webrat65.

55

http://seleniumhq.org [23.9.2010] http://grinder.sourceforge.net [23.9.2010] 57 http://www.google.com/websiteoptimizer [23.9.2010] 58 http://www.junit.org [23.9.2010] 59 http://www.nunit.org [23.9.2010] 60 https://h10078.www1.hp.com/cda/hpms/display/main/hpms_content.jsp? zn=bto&cp=1-11-15-25^849_4000_100__ [23.9.2010] 61 https://h10078.www1.hp.com/cda/hpms/display/main/hpms_content.jsp? zn=bto&cp=1-11-126-17^8_4000_100__ [23.9.2010] 62 http://www.webtrends.com [23.9.2010] 63 http://www.telerik.com/products/web-testing-tools/webaii-framework-features.aspx [23.9.2010] 64 http://www.ibm.com/software/rational [23.9.2010] 65 http://github.com/brynary/webrat [23.9.2010] - 20 56


2.5 Werkzeuge Im Folgenden werden zehn beliebte Werkzeuge für verschiedene Aspekte des WebauftrittTestens vorgestellt. Damit soll ein Überblick geschaffen werden, wobei mehrere Quellcode-Beispiele einen Einblick in die praktische Verwendung bieten.

2.5.1 Serverseitige Komponententests Komponententests für die serverseitige Anwendungslogik können mit Frameworks der xUnit-Familie implementiert werden. Der Extreme Programming-Mitbegründer Ron Jeffries unterhält eine ausführliche Liste solcher Werkzeuge auf http://www.xprogramming.com/ software.htm unter dem Abschnitt “Unit Testing”. PHPUnit (phpunit.de) PHPUnit ist ein Komponententestframework für die Skriptsprache PHP, die sich im Webbereich grosser Verbreitung erfreut. Das Werkzeug dient mit einer an xUnit angelehnten Schnittstelle als KomponententestFramework, und berichtet über die Resultate von durchgelaufenen Tests, beispielsweise mit Testabdeckungs-Berichten. Im Folgenden ein beispielhafter Testfall “LoginLogout” mit den zwei Testmethoden “testLogin()” und “testLogout()”. Die Methoden “setUp()” und “tearDown()” werden vom Test-Framework vor beziehungsweise nach dem Abarbeiten der Testmethoden eines Testfalls ausgeführt. Im Beispiel erstellt “setUp()” mittels einer externen Hilfsklasse ein Benutzerobjekt, und “tearDown()” stellt die verwendete Datenbank zum Schluss des Testfalls wieder auf den Ursprungszustand zurück.

- 21 -


class LoginLogoutTest extends PHPUnit_Framework_TestCase { ! ! public function setUp() { ! ! TestHelperFunctions::createTestUser(); ! } ! ! ! ! ! ! ! ! ! ! ! ! !

public function tearDown() { ! TestHelperFunctions::clearDb(); } public ! ! ! }

function testLogin() { $this->assertTrue( ! LoginLogout::login('username', 'password'), ! 'Login failed');

public ! ! ! ! }

function testLogout() { LoginLogout::logout(); $this->assertNull( ! My_Session::getUserId(), ! 'Logout did not clear session');

! }

Die mit “assert” beginnenden Methoden sind die eigentlichen Schnittstellen zum TestFramework. Mit ihnen wird überprüft, ob eine Variable (in diesem Fall der Rückgabewert einer Methode) die geforderten Bedingungen erfüllt. So schlägt “assertTrue()” Alarm, wenn der erste Parameter nicht true ist. PHPUnit kann in phpUnderControl66, eine Erweiterung für den kontinuierlichen Integrationsserver CruiseControl 67, integriert werden. Damit kann die kontinuierliche Ausführung eines Erstellungsprozesses mit dem Durchlaufen von Komponententests verknüpft werden. Entwickler erhalten

Abb. 6: Testabdeckung mit phpUnderControl

auf diese Weise zügig Rückmeldungen über allfällig fehlschlagende Tests im Gesamtprodukt.

66 67

http://phpundercontrol.org [7.9.2010] http://cruisecontrol.sourceforge.net [7.9.2010] - 22 -


2.5.2 JavaScript Komponententests Mit dem Siegeszug von JavaScript als clientseitige Web-Programmiersprache 68 steigt das Bedürfnis nach JavaScript-Komponententests. In einem Browser laufend stellt dabei insbesondere die automatisierte Ausführung und Analyse der Tests eine Herausforderung dar. FireUnit (fireunit.org) FireUnit bietet Komponententest-Schnittstellen in JavaScript an und stellt Ergebnisse in der Mozilla Firefox-Webentwicklungs-Erweiterung Firebug an. Ursprünglich für die Entwicklung von Firefox-Erweiterungen erdacht69 , kann FireUnit auch für das Testen von Webauftritten verwendet werden. Die Software bietet einige Methoden zur Simulation von Benutzereingaben an, und enthält grundlegende xUnit-Schnittstellen: fireunit.ok(true, "This should pass"); fireunit.ok(false, "This should fail"); fireunit.compare("This is expected", "This isn't expected", ! "Texts differ");

Die Testsergebnisse werden in Firebug tabellarisch aufgeführt:

Abb. 7: FireUnit-Ergebnisse in Firebug

68 69

Crockford, 2008 http://www.softwareishard.com/blog/firebug/fireunit-testing-in-the-firebug-world/ [7.9.2010] - 23 -


QUnit (docs.jquery.com/Qunit) Die Funktionalität des JavaScript-Frameworks jQuery wird durch QUnit-Komponententests geprüft71 . QUnit kann aber ebenfalls für das Testen beliebiger JavaScript Anwendungen verwendet werden. Als Assertions stehen ok(), equals() und same() zur Verfügung: test("A basic test example", function() { ! ok(true, "This should pass"); ! ok(false, "This should fail"); ! equals("This is expected", "This isn't expected", ! ! "Texts differ"); });

Die Resultate werden direkt im getesteten HTML-Dokument angezeigt, was bedeutet, dass das Framework browserübergreifend verwendet werden kann:

Abb. 8: QUnits Ergebnisanzeige

2.5.3 HTTP Integrationstests Beim Einsatz spezieller HTTP-Dienste wie Reverse Proxys oder gar selbst entwickelten HTTP-Servern kann es nötig sein, die HTTP-Kommunikation zu testen. HTTest (htt.sourceforge.net) Das in C entwickelte Test-Framework HTTest kann durch eine simple Skriptsprache gesteuert HTTP-Clients und -Server simulieren, wobei die stattfindende Kommunikation mit Bedingungen überprüft wird. Zusätzlich können Eingaben mit externen Programmaufrufen generiert und Ausgaben an solche weitergeleitet werden. Folgendes Skript ruft eine nicht vorhandene Datei auf dem “sbb.ch”-Server auf und überprüft, ob eine 404-Antwort zurückkommt: CLIENT _REQ sbb.ch 80 __GET /doesnotexist HTTP/1.1 __Host: sbb.ch __ _EXPECT . "HTTP/1.1 404 Not Found" _WAIT END - 24 -


Während der Ausführung der Befehle zeigt HTTest die gesamte HTTP-Kommunikation auf der Standardausgabe an.

2.5.4 Browser Integrationstests Neben der Client-Server-Kommunikation auf HTTP-Ebene, also im OSISchichtenmodell71 , sollen vielfach auch die darauf aufbauenden Inhalte getestet werden. Diese konkreten Anwendungsinhalte liegen beispielsweise strukturiert als HTMLDokumente vor. Eine strukturelle Analyse bietet sich an, um Bedingungen an diese Inhalte zu formulieren. Dazu muss im Allgemeinen die Syntaxanalyse eines Browsers nachempfunden werden, um anschliessend die entstandenen Datenstrukturen zu überprüfen. HtmlUnit (htmlunit.sourceforge.net) HtmlUnit ist ein in Java implementierter Webbrowser ohne grafische Benutzerschnittstelle. Die Software kann wie ein klassischer Browser Webseiten laden, CSS anwenden und JavaScript ausführen. Die resultierenden Webseiten werden jedoch nicht auf den Bildschirm gerendert, sondern stehen über Java-Schnittstellen zur Verfügung. Die angebotene API erinnert stark an die übliche Verwendungsweise eines Browsers. So können Forms ausgefüllt und Links verfolgt werden. Gleichzeitig können via Document Object Model (DOM)72 an die Dokumentenstruktur gestellte Bedingungen überprüft werden. Im folgenden Beispiel soll in einem JUnit-Testfall in Kombination mit HtmlUnit die Referenz eines Hyperlinks (“href”) auf der Indexdatei des “sbb.ch”-Servers geprüft werden: public class SbbTest extends TestCase { ! ! ! ! ! ! !

public ! ! ! ! ! }

void testCargo() throws Exception { WebClient client = new WebClient(BrowserVersion.FIREFOX_3); HtmlPage page =! client.getPage("http://www.sbb.ch"); HtmlAnchor anchor = page.getAnchorByText("Cargo"); assertEquals(anchor.getHrefAttribute(), ! ! ! "http://www.sbbcargo.com");

}

Dabei wird zuerst eine Browser-Instanz erstellt (“WebClient”), wobei hier ein “Firefox 3” simuliert werden soll. Nachdem die gewünschte Webseite geladen ist, wird mittles

71 72

Open Systems Interconnection model, ISO-Schichtenmodell von Kommunikationsprotokollen Schnittstellenspezifikation für den HTML- und XML-Zugriff - 25 -


“getAnchorByText()” auf einen spezifischen Hyperlink in der HTML-Struktur zugegriffen, dessen “href”-Attribut mit einer Bedingung geprüft wird. Als Browser-Simulation wird HtmlUnit in verschiedensten Test-Frameworks verwendet. Gerade weil keine GUI verwendet wird, lässt sich HtmlUnit verlässlich automatisiert steuern. Die Funktionalität der Software hinkt dafür den realen Browserversionen hinterher, speziell der JavaScript-Funktionsumfang, welcher auf Mozillas Rhino basiert. Selenium (seleniumhq.org) Selenium ist ein vielseitiges Integrationstest-Framework fürs Web. Es umfasst einerseits eine Firefox-Erweiterung, die das Aufzeichnen und Abspielen von Testszenarien erlaubt (Selenium IDE) und andererseits ein System für die automatisierte Kontrolle von Webbrowsern mittels Schnittstellen (Selenium Remote Control [RC]). Selenium RC besteht aus einem Server, der Browser öffnet, schliesst und ihnen als Proxy dient. Mit Hilfe dieses Proxys kann in Echtzeit JavaScript in eine geladene Webseite eingeschleust werden. Über Schnittstellen, die für

Abb. 8: Selenium RC

verschiedene Programmiersprachen zur Verfügung stehen, wird dieser “Remote Control Server” kontrolliert. Durch eigenständige Programme, oder mittels einem xUnit-Framework können damit in Java, Python, Ruby, C#, Perl oder PHP die Browser Firefox, Internet Explorer, Safari sowie Chrome ferngesteuert werden. Beispielhaft wird mit Java erneut das “href”-Attribut eines Links auf “sbb.ch” geprüft:

- 26 -


public class SbbTest extends SeleneseTestCase { ! ! public void setUp() throws Exception { ! ! setUp("http://www.sbb.ch/", "*firefox"); ! } ! ! ! ! ! ! ! }

public ! ! ! ! }

void testCargo() throws Exception { selenium.open("/"); String cargoHref = ! selenium.getAttribute("//a[text()='Cargo']@href"); assertEquals(cargoHref, "http://www.sbbcargo.com");

Der Testfall erbt im Unterschied zu HtmlUnit nicht direkt von JUnits TestCase, sondern von einer davon abgeleitete Klasse SeleneseTestCase. Damit werden im Testfall verschiedene Selenium-Methoden verfügbar. Ausserdem startet Selenium RC anstelle einer Browsersimulation eine richtige FirefoxInstanz, in welcher die “sbb.ch”-Webseite geladen wird, um anschliessend per XPath auf das “href”-Attribut zuzugreifen. Um Selenium-Tests schneller und auf mehreren Betriebssystemen gleichzeitig laufen zu lassen, wird Selenium Grid angeboten. Damit können in einem Testset Selenium RCInstanzen auf verschiedenen Rechnern angesprochen werden. Um vom Geschwindigkeitsvorteil zu profitieren, müssen Tests parallel ablaufen - für JUnit verwendet man beispielsweise Parallel JUnit73 , welches Testfälle in Threads ausführt. Um die Verwirrung komplett zu machen, wird im Moment an Selenium 2 gearbeitet, eine Verschmelzung von Selenium und WebDriver (deshalb auch Selenium WebDriver genannt). WebDriver ist ein ursprünglich von Google veröffentlichtes74 Projekt, mit dem ebenfalls verschiedenste Webbrowser automatisch gesteuert werden können. Anstatt dies mittels JavaScript zu lösen, werden aber höherschichtige Ansätze verwendet, die spezifisch auf den jeweiligen Browser angepasst sind. So wird beispielsweise Firefox über eine FirefoxErweiterung gesteuert. Mit der Verwendung von WebDriver können in Selenium 2 Tests in realen Browsern zügiger und verlässlicher ausgeführt werden.

73 74

https://parallel-junit.dev.java.net [7.9.2010] http://google-opensource.blogspot.com/2009/05/introducing-webdriver.html [7.9.2010] - 27 -


Rund um Selenium Im Folgenden eine Auswahl an Test-Software aus dem Selenium-Umfeld. • Sahi (sahi.co.in) basiert ähnlich wie Selenium 1 auf einem Proxy-Server, der im Browser eingetragen wird und diesem JavaScript-Befehle unterschiebt. Durch die Implementierung des Servers in Java ist Sahi browser- und betriebssystemunabhängig. Die Tests selbst werden mit Methoden wie _click() und _div() in JavaScript entwickelt. • Watir (watir.com) ist ein in Ruby geschriebenes Framework, das ähnlich wie WebDriver über verschiedene Betriebssystem- und Applikationsschnittstellen einen Webbrowser kontrolliert. So wird beispielsweise der Internet Explorer über COM75-Schnittstellen angesprochen. Es existieren einige von Watir inspirierte Test-Frameworks in anderen Programmiersprachen: WatiN 76 in C#, Watij77 in Java, oder das Perl-Modul Win32::Watir78 . • CubicTest (http://cubictest.seleniumhq.org) ist eine Eclipse79-Erweiterung, die es erlaubt Webseiten-Tests mit einer GUI als Flussdiagramm zusammenzuklicken. Ganze Benutzergeschichten können mit pfeilartigen Verbindungen zwischen Kästchen für Klicks, Text-Eingaben und Bedingungen zusammengestellt werden. Die fertigen Tests werden durch Selenium oder Watir ausgeführt.

2.5.5 Last Systemtests Auch für nicht-funktionale Anforderungen kann es nötig sein Tests zu automatisieren. Mit Lasttests soll geprüft werden, wie sich eine Webanwendung bei vielen Anfragen verhält. Je nach verwendeter Technik gibt es dutzende mögliche Flaschenhälse. Um diese zu erkennen und zu analysieren, muss auf dem entsprechenden System hohe Last simuliert werden. p-unit (p-unit.sourceforge.net) Das seit zwei Jahren nicht mehr weiterentwickelte Benchmarking-Framework p-unit bietet simple Java-Schnittstellen an, um die Laufzeit und den Speicherbedarf von ausgeführtem Java-Code zu messen.

75

Component Object Model, Interprozesskommunikation unter Windows http://watin.sourceforge.net [7.9.2010] 77 http://watij.com [7.9.2010] 78 http://search.cpan.org/dist/Win32-Watir/ [7.9.2010] 79 http://www.eclipse.org [7.9.2010] - 28 76


Mit einem solchen Werkzeug kann beispielsweise die Ausführungszeit der Anwendungslogik einer Webanwendung gemessen werden. Dabei kann das Lastverhalten von Datenbankanfragen, der Dateizugriff oder die Ausführung von externen Skripten Objekt von Interesse sein. Folgendes Beispiel misst den Zeitbedarf für das Berechnen aller Quadratwurzeln zwischen 1 und 500ʼ000ʼ000 mit Math.sqrt(): public class SqrtTest { ! ! !

public static void main(String[] args) { ! new SoloRunner().run(SqrtTest.class); }

! ! ! ! ! ! }

public ! ! ! }

void test500mio() { for (long i=1; i<=500000000.0; i++) { ! Math.sqrt(i); }

Das Ergebnis wird auf die Konsole ausgegeben: test10mio() - [1211.751ms]

Es können auch Grafiken und PDF-Reporte generiert werden. ApacheBench (httpd.apache.org/docs/2.2/programs/ab.html) ApacheBench (ab) ist Teil des Apache HTTP Servers und dient dazu die Antwortzeiten eines Webservers zu messen. Das Kommandozeilen-Werkzeug kann über Parameter dazu aufgefordert werden, eine bestimmte Anzahl an HTTP-Anfragen gleichzeitig und wiederholt an einen Server zu schicken, und schlussendlich über die Antwortzeiten zu berichten. Ein solcher Bericht enthält unter Anderem den Zeitbedarf verschiedener Phasen der HTTP-Kommunikation: Connection Times (ms) min mean[+/-sd] median Connect: 23 35 11.7 30 Processing: 166 181 10.0 180 Waiting: 40 50 6.2 51 Total: 201 215 13.2 216

max 55 194 59 244

Sofern das Performanzverhalten der Anwendungslogik auf dem Server getestet wird, sollte darauf geachtet werden, dass ab auf dem gleichen Rechner wie der HTTP Server läuft, um ohne den Flaschenhals Netzwerk viel Last erzeugen zu können. - 29 -


2.5.6 Sicherheit Systemtests Es gibt eine Menge an kommerziellen und quelloffenen Sicherheits-Werkzeugen für Webanwendungen. Die meisten nennen sich Scanner und versuchen semi-automatisiert nach Schwachstellen wie SQL-Injection-Lücken zu suchen. Ein ausführliche Liste an Programmen wird vom Web Application Security Consortium (WASC) unterhalten: http:// projects.webappsec.org/Web-Application-Security-Scanner-List. Im Folgenden werden zwei solche Werkzeuge kurz vorgestellt. Skipfish (code.google.com/p/skipfish) Das von Google initiierte Skipfish ist ein klassischer Sicherheits-Scanner. Google selbst nennt es auch ein Erkundungs-Werkzeug. Herausragend ist vor allem die Performanz der Software. Eine schnelle HTTP-Implementierung in C soll bis zu 7000 Anfragen pro Sekunde an einen lokalen Server ermöglichen80 . Die Software sucht nach SQL-Injection-, XSS- und Pufferüberlauf-Lücken, aber auch nach weniger dramatischen Fehlern wie falschen MIME-Typen oder HTTP-Statuscodes. Die Erkundungs-Ergebnisse werden in einer interaktiv navigierbaren HTML-Seite präsentiert. w3af (w3af.org) Das Web Application Attack and Audit Framework (w3af) ist ein Sicherheits-Scanner für Webanwendungen, der inzwischen von Rapid781 gesponsert wird - eine Sicherheitsfirma die 200982 das Penetrationstest-Framework Metasploit83 gekauft hat. Über eine Plugin-Infrastruktur verwaltet w3af die verfügbaren Scantaktiken. Grössere Plugin-Kategorien sind “evasion” zum Umgehen von Intrusion Detection Systemen 84, “grep” zum generellen Durchsuchen von HTTP-Antworten beispielsweise auf IP-Adressen, oder Kreditkartennummern und “audit” zum eigentlichen Prüfen auf Sicherheitslücken. Dabei werden die üblichen Verdächtigen wie XSS-, SQL-Injection-, XPath-Injection- oder Dateiupload-Lücken erkannt.

80

http://code.google.com/p/skipfish/wiki/SkipfishDoc [7.9.2010] http://www.rapid7.com [7.9.2010] 82 http://www.rapid7.com/metasploit-announcement.jsp [7.9.2010] 83 http://www.metasploit.com [7.9.2010] 84 System zur Erkennung von Angriffen und Einbrüchen in Computersysteme - 30 81


3. Webseiten Layout-Testen: Screencompare 3.1 Problem Etliche Faktoren machen es unter gewissen Umständen wünschenswert, die clientseitige Präsentation einer Webanwendung auf visueller Ebene zu überprüfen, und diesen Prozess zu automatisieren.

3.1.1 Diversifizierte Client-Landschaft Die Darstellung und Ausführung von Webanwendungs-Benutzerschnittstellen wird durch eine Vielzahl von Webbrowsern übernommen. Deren Interpretierung von HTML-, CSSund JavaScript-Anweisungen entscheidet darüber, wie ein Anwender die Webseiten zu Gesicht bekommt. Es gibt seit jeher Bestrebungen, Webtechnologien über Browsergrenzen hinweg zu standardisieren. Die wohl einflussreichste Organisation diesbezüglich ist das World Wide Web Consortium (W3C)85, welches Standardisierungsdokumente zu HTML, XHTML, CSS, DOM, CGI und vielen weiteren Technologien veröffentlicht. Der ECMAScript-Dialekt JavaScript wird hingegen von der Ecma International86 standardisiert. Verschiedene Faktoren führen aber auch heute noch zu schlechter Interoperabilität zwischen Browsern verschiedener Hersteller. Einerseits werden die Standards unvollständig oder fehlerhaft umgesetzt, andererseits werden browserspezifische Funktionalitäten eingeführt, da die Standards beispielsweise als unvollständig erachtet werden87. Dies führt dazu, dass bei der Entwicklung von Webauftritten darauf geachtet werden muss, dass die Benutzerschnittstelle des Produkts bei den Endanwendern auch wirklich so aussieht und funktioniert wie erdacht. Es hat sich eingebürgert vor dem Produktstart einer Webanwendung die Benutzerschnittstelle in mindestens zwei bis drei verschiedenen Webbrowsern einem Abnahmetest zu unterziehen. Der Grossteil eingesetzter Browser wird von fünf verschiedenen Unternehmen entwickelt oder getragen, namentlich Microsoft (Internet Explorer), Mozilla (Firefox), Google (Chrome), Apple (Safari) und Opera. Das kalifornische Webanalyse-Unternehmen Net Applications88 sammelt Benutzerinformationen von nach eigenen Angaben 160 Millionen

85

http://www.w3.org [7.9.2010] http://www.ecma-international.org [7.9.2010] 87 Bspw. Internet Explorer box model Fehler, "-moz-*", "-ms-*" oder "-webkit-*" CSS-Eigenschaften 88 http://www.netapplications.com [7.9.2010] 86

- 31 -


Webauftritt-Besuchern im Monat89. Anhand dieser öffentlich zugänglichen Daten setzt sich der Browser-Markt im Mai 2010 wie folgt zusammen: Webbrowser (Andere) Opera Safari

Layout-Engines Presto(Andere) (Opera)

IE6

WebKit (Safari+Chrome)

Chrome

Trident (IE6+7)

IE7 Gecko (Firefox)

Firefox

IE8 comp. mode

IE8

Trident 4 (IE8)

Das erste Diagramm unterscheidet zwischen Browser-Namen und beim Internet Explorer auch -Versionen. Das Zweite zeigt verschiedene sogenannte Layout-Engines, also die einem Browser zugrundeliegende Software, welche für das HTML-Rendering zuständig ist. Die Zahlen belegen, dass eine Menge verschiedener Web-Clients verwendet wird. Auch der durch seine eigenwillige Interpretation von Webstandards bei Entwicklern verachtete90 Internet Explorer 6 hat neun Jahre nach seiner Einführung noch einen beachtlichen Marktanteil. Auch die neusten Versionen von Browsern machen Entwicklern in mancher Hinsicht das Leben schwer. Dies ist mehrheitlich darauf zurückzuführen, dass sich die verwendeten Technologien rasant weiterentwickeln. So befinden sich zur Zeit die viel gelobten Standards HTML5 und CSS 3 in Entwicklung. Im Rennen um gewiefte Benutzerschnittstellen für Webanwendungen werden Vorabversionen und eigene Interpretationen dieser Technologien implementiert, wodurch Webauftritte wieder in den verschiedenen Browsern getestet werden müssen.

3.1.2 Pixelgenaues Design Es ist umstritten, wie sehr sich das Layout von Webseiten in verschiedenen Browsern unterscheiden darf91 . Vielfach macht es Sinn, nur einige Design-Bausteine genau zu definieren, und diese in ein loses, mehrheitlich durch seine Struktur beschriebenes HTMLDokument einzubetten. Dadurch gewinnt der Anwender gewisse Freiheiten, indem er die

89

http://www.netmarketshare.com [7.9.2010] http://www.bringdownie6.com [7.9.2010] 91 Bspw. http://boagworld.com/technology/effective-browser-support [23.9.2010] - 32 90


Präsentation einer Webseite an eigene Bedürfnisse anpassen kann. Gleichzeitig wird das Design dadurch eher Inhaltsagnostisch, verträgt sich also mit aller Art von textuellen und multimedialen Inhalten. Trotzdem kann es eine Anforderung sein, gewisse Design-Elemente oder ganze Webseiten pixelgenau zu implementieren. Meist werden solche Designs in einem Bildbearbeitungs- oder Layoutprogramm entworfen, und müssen dann mittels HTML und CSS mit möglichst allen gängigen Browsern kompatibel umgesetzt werden. Solche pixelgenauen Designs sind vielfach bildlastig, werden aber vemehrt auch HTMLMarkup und CSS gestützt implementiert. Dadurch wird es meist schwieriger eine korrekte

Abb. 9: CSS-Aufklappmenüs können Pixelgenauigkeit benötigen

Wiedergabe über Browsergrenzen hinweg zu erreichen.

3.1.3 Bedarf nach visuellem Layout-Testen Obig genannte Umstände führen dazu, dass die Präsentation gewisser Webseiten in verschiedenen Browsern mit einer Referenz verglichen wird. Dabei sind üblicherweise kleine Unterschiede wie beispielsweise in der Schrift-Darstellungen hinnehmbar, an anderen Stellen wird allerdings Pixelgenauigkeit gefodert. Zur Überprüfung kann zum Beispiel eine Referenz über den Browser überlagert werden. Smile Designer Smile (9elements.com/io/?page_id=54) Smile Designer Smile ist ein Plugin für das JavaScript-Framework jQuery. Mit ihm kann ein Entwickler mit einigen Zeilen Quellcode eine Bilddatei über eine Webseite im Browser legen. Diese liegt dann halbdurchsichtig und mit der Maus verschiebbar als Referenz über der Webseite. Pixel Perfect (pixelperfectplugin.com) Die fast identische Funktionalität bietet Pixel Perfect. Als FirefoxFirebug-Plugin ist es allerdings ohne Programmieraufwand einsetzbar und bietet mit einer einfachen GUI etwas mehr Komfort. Allerdings ist es nur in Firefox verwendbar. - 33 -

Abb. 10: ReferenzÜberlagerung


Das Überlagern einer Bilddatei vereinfacht das Überprüfen der visuellen Präsentation von Webseiten, ist aber ein manueller Prozess. Bei komplexen Webanwendungen wird üblicherweise versucht server- wie auch clientseitigen Quellcode für mehrere Webseiten wiederzuverwenden. Dadurch wird einerseits Code-Duplizierung verhindert, was die Wart-, Test- und Erweiterbarkeit verbessert. Andererseits können dadurch clientseitige Hilfsdokumente wie CSS-Dateien wiederverwendet werden, so dass sich die Übertragungszeiten von Webseiten verkürzen. Die dadurch entstehenden Abhängigkeiten innerhalb der Anwendung haben zur Folge, dass sich kleine Änderungen in einzelnen Quell-Dateien vielfach auf grosse Teile der Software auswirken. In Verbindung mit einer grossen Anzahl unterschiedlicher Webseiten eines Webauftritts wird das zu einem Problem: Änderung eines Enwicklers an einer einzelnen Webseite können ungewollt Auswirkungen auf andere Webseiten haben, welche nur mit grossem Aufwand manuell zu entdecken sind. Eine solche Nebenwirkung einer Softwareänderung wird Regression, das Überprüfen auf solche Unannehmlichkeiten Regressionstest92 genannt. Weil diese Tests bei möglichst jeder Code-Änderung durchgeführt werden sollten, ist es sinnvoll sie zu automatisieren. Für Web-Benutzerschnittstellen gilt das genauso wie für die Anwendungslogik. Beispielsweise kann die Änderung einer einzelnen CSS-Regel das Aussehen eines ganzen Webauftritts verändern, und damit unter Umständen in nur einer von hunderten Webseiten einen Layout-Fehler hervorrufen. In solchen Fälle sind automatisierte Regressionstests des Layouts wünschenswert.

3.2 Lösungsansatz Als Ansatz für visuelle Layouttests stelle ich eine automatisierte Variante von ReferenzÜberlagerung auf Webseiten vor. Eine konkrete Implementierung in Java nenne ich Screencompare. Dabei sind folgende Anforderungen relevant: • Browserübergreifend: Es sollen die Render-Ergebnisse verschiedener Browser prüfbar sein, um deren Eigenheiten testbar zu machen. • Selektiv: Nicht immer muss das Layout einer ganze Webseite pixelgenau geprüft werden, es müssen auch Ausschnitte vergleichbar sein. • JavaScript-kompatibel: Um JavaScript-lastige Webseiten zu testen, sollen vor der Referenz-Überlagerung JavaScript-Anweisungen ausgeführt werden können. • Regressionstest-kompatibel: Damit verschiedene Versionen eines Webauftritts verglichen werden können, müssen Render-Ergebnisse speicherbar sein. 92

BS 7925-1 - 34 -


• Automatisiert: Der visuelle Vergleich soll automatisiert stattfinden. Grundlegend funktioniert das Ganze analog einer manuellen Referenz-Überlagerung. Es wird also eine Bilddatei (Referenz) mit dem Render-Ergebnis eines Browsers verglichen.

Um eine Webseite automatisiert zu laden und eventuelles JavaScript auszuführen muss das Test-Framework den Browser steuern können. Dabei soll die existierende Funktionalität von Selenium verwendet werden (es kämen aber auch andere Produkte in Frage, siehe Kapitel 2.5.4). Der Einfachheit halber wird nur der Viewport, also der sichtbare Teil einer Webseite im Browser, mit der Referenz verglichen. Der eigentliche Vergleich von Referenz und Rendering findet automatisiert mittels eines Pixelvergleichs statt.

3.3 Funktionsweise 3.3.1 Testablauf Screencompare vergleicht Bilder des Viewports eines Webbrowsers. Dazu wird der zu verwendende Browser per Selenium ferngesteuert, um danach aus einem Screenshot des ganzen Bildschirms den eigentlichen Viewport zu extrahieren. Die Erkennung des Viewports auf dem Screenshot geschieht mittels farbbasierter Bildfreistellung, indem vor jedem Test eine rein grüne Webseite im Browser angezeigt wird.

Obige Bildreihe stellt diesen Vorgang dar. Nachdem der Webbrowser gestartet ist, wird der Hintergrund der Webseite mittels JavaScript grün eingefärbt. Dabei wird zusätzlich sichergestellt, dass das Browserfenster in maximaler Grösse dargestellt wird und - 35 -


vollständig sichtbar ist. Screencompare macht einen Screenshot und erkennt anhand der grünen Fläche die Position und Grösse des Viewports.

Danach werden die eigentlichen Webseiten aufgerufen, welche getestet werden sollen. Da die Viewport-Position nun bekannt ist, kann aus einem Screenshot direkt der Viewport mit der angezeigten Webseite extrahiert werden. Zum Vergleich der aufgenommenen Webseiten-Bilder stehen einige Methoden zur Verfügung, welche auf unterschiedliche Weise deren Differenz berechnen und ausgeben. Das Framework ist darauf ausgelegt, in einem JUnit-ähnlichen Komponententest verwendet zu werden. Dazu wird JUnits TestCase als ScreencompareTestCase erweitert. Neben den gängigen JUnit-Methoden steht darin Funktionalität für die Browser-Steuerung, die ViewportAufnahme und für den ViewportVergleich zur Verfügung. ScreencompareTestCase verwendet einen “Treiber”, welcher die Fernsteuerung des Browsers übernimmt. Im Normalfall wird Selenium RC verwendet, allerdings steht auch eine Implementierung für Selenium WebDriver zur Verfügung. Ausserdem können eigene Treiber als Implementierung der abstrakten

Abb. 11: Funktionsprinzip Screencompare

Klasse Driver geschrieben werden.

Die beiden Selenium-Treiber unterstützen zum jetztigen Zeitpunkt folgende Browser: - 36 -


Remote Control (Windows)

Remote Control (Mac OS X)

WebDriver (Windows)

WebDriver (Mac OS X)

Google Chrome

Firefox

Internet Explorer

Safari

Screencompare läuft derzeit auf Windows und Mac OS X. Betriebssystem-abhängiger Code wird benötigt, um sicherzustellen, dass der Browser im Fenstersystem für den Screenshot sichtbar ist. Dies wird entweder mit AppleScript oder einer kleinen C++-MFCAnwendung erledigt.

3.3.2 Verwendung Zur sinnvollen Auswertung aufgenommener Viewport-Bilder stehen in ScreencompareTestCase einige öffentliche Methoden zur Verfügung. Im Folgenden wird auf diese Funktionalität anhand von Beispielen eingegangen. Grundlegend empfiehlt es sich, einen von ScreencompareTestCase erbenden Testfall zu erstellen: public class ExampleTest extends ScreencompareTestCase { ! ! ! ! !

public ! ! ! }

void test() throws Exception { start("http://www.google.ch", Browser.FIREFOX); captureScreen().save(); stop();

}

Viewport-Aufnahmen werden jeweils von start() und stop() umrahmt. Damit wird der entsprechende Browser mit der im Argument übergebenen URL geöffnet, beziehungsweise wieder geschlossen. Die Methode captureScreen() fängt die angezeigte Webseite ein und gibt eine Instanz der Klasse Screen zurück. Diese hält neben dem eigentlich Bild auch Metainformationen wie die URL, den verwendeten Browser und den Namen des entsprechenden Komponententests. Während ein Browser geöffnet ist stehen unter Anderem folgende Methoden zur Verfügung: • js(String javascript): Führt übergebenes JavaScript aus. • setBackground(Color color): Setzt die Seiten-Hintergrundfarbe. Nützlich für eigene farbbasierte Bildfreistellung. - 37 -


• hideElement(String elementId): Versteckt ein Element, um beispielsweise Werbebanner vom Bildvergleich auszunehmen. • hideText(): Versteckt alle Textstellen einer Seite, um das rein graphische Layout einer Seite zu prüfen. • waitElementVisible(String elementId): Unterbricht die Programmausführung, bis das entsprechende Element sichtbar ist. Dies kann nützlich sein, wenn vor der ViewportAufnahme beispielsweise auf eine AJAX-Antwort gewartet werden soll. Zur tatsächlichen Auswertung von Bedingungen steht beispielsweise verifySame() zur Verfügung, welches zwei Screens vergleicht. Im folgenden Beispiel wird das RenderErgebnis zweier Webseiten im Internet Explorer und Firefox verglichen: public class CompareFirefoxIETest extends ScreencompareTestCase { ! ! !

public void test() throws Exception { ! String[] urls = {"http://www.google.ch", ! ! ! ! "http://weatherflash.com/"};

! ! ! ! ! ! ! ! ! ! ! !

! ! ! ! ! ! ! ! ! ! ! }

for (String url:urls) { ! start(url, Browser.FIREFOX); ! Screen firefox = captureScreen(); ! stop(); ! ! start(url, Browser.IE); ! Screen ie = captureScreen(); ! stop(); ! ! verifySame(firefox, ie, 0.05f, Alignment.TOP_CENTER); }

}

Dabei wird verifySame() neben den beiden Screens ein Schwellenwert für Bildunterschiede und eine Ausrichtungs-Anweisung übergeben. Die beiden Aufnahmen werden im Beispiel mittig oben übereinandergelegt, wobei eine Ausnahmesituation (Exception) ausgelöst wird, sobald mehr als 5% der Pixel Unterschiede aufweisen. Falls dieser Schwellenwert überschritten wird, und der Testfall entsprechend fehlschlägt, wird zusätzlich ein PDF-Report generiert, anhand von dem später untersucht werden kann, wieso der Testfall fehlschlug.

- 38 -


Abb. 12: PDF-Report mit Firefox- und IE6-Screen sowie deren Differenz Anhand eines weiteren Beispiels soll erläutert werden, wie Elemente auf einer Seite vor der Viewport-Aufnahme versteckt werden können. Dies kann nützlich sein, wenn eine Seite beispielsweise Werbebanner enthält, welche aber nicht Teil des Tests sein sollen. public class HideTest extends ScreencompareTestCase { ! public ! ! the-day/", ! ! ! ! ! ! ! ! ! ! ! ! ! }

void test() throws Exception { start("http://photography.nationalgeographic.com/photo-ofBrowser.FIREFOX); captureScreen().save("nationalgeographic-1.png"); hideElement("headerboard"); captureScreen().save("nationalgeographic-2.png"); hideText(); captureScreen().save("nationalgeographic-3.png"); stop();

}

Im Beispiel wird mittels hideElement() das “headerboard” einer National GeographicWebseite entfernt, welches einen Werbebanner enthält. In einem zweiten Schritt versteckt hideText() alle Textstellen auf der Seite. Da Schriftzeichen in verschiedenen Browsern vielfach verschieden angezeigt werden, kann es wünschenswert sein, diese vor einem Referenzvergleich auszublenden. Nach jedem Zwischenschritt wird der Screen abgespeichert:

In kurzen Entwicklungszyklen aktualisierte Webauftritte erfordern besondere Wachsamkeit bezüglich der korrekten Darstellung im Webbrowser. Eine überschaubare Änderung am Quellcode einer Webanwendung kann Render-Probleme in einzelnen ClientKonfigurationen auslösen, welche nur mit grossem Aufwand manuell auffindbar sind.

- 39 -


Screencompare bietet verschiedene Möglichkeiten, automatisierte Regressionstests der visuellen Darstellung einer Webanwendung durchzuführen, indem Screens verschiedener Programmversionen verglichen werden. Im Folgenden Beispiel wird das Layout einer Webseite abgespeichert, um es später mit dem Referenzlayout einer neuen Webauftrittsversion zu vergleichen. Dieser erste Teil des Regressionstests öffnet zwei Webseiten und speichert deren Darstellung als Bilddatei ab: public class RegressionStore extends ScreencompareTestCase { ! ! !

public void test() throws Exception { ! String[] urls = {"http://www.retokaiser.com/", "http://www.retokaiser.com/Unterrichtsmaterialien Informatik/"};

! ! ! ! ! !

! ! ! ! ! }

for (String url:urls) { ! start(url, Browser.SAFARI); ! captureScreen().save(); ! stop(); }

}

Dabei öffnet Screenreport den Safari-Browser und legt die aufgenommenen Bilddateien im Datenverzeichnis ab.

Die Entwicklung an diesem Webauftritt kann nun weitergeführt werden, mit dem Wissen, dass ein Sollzustand des Layouts vorhanden ist. Folgender Test vergleicht eine neuere Version des Webauftritts mit diesem abgespeicherten Zustand:

- 40 -


public class RegressionStoredTest extends ScreencompareTestCase { ! ! !

public void test() throws Exception { ! String[] urls = {"http://www.retokaiser.com/", "http://www.retokaiser.com/Unterrichtsmaterialien Informatik/"};

! ! ! ! ! ! !

! ! ! ! ! ! }

for (String url:urls) { ! start(url, Browser.SAFARI); ! Screen reference = loadScreen(url, Browser.SAFARI); ! verifySame(captureScreen(), reference); ! stop(); }

}

In der Schleife werden die aufgenommenen Screens mit den vom Datenverzeichnis geladenen Referenzen verglichen. Unter der Annahme, dass sich das visuelle Erscheinungsbild des Webauftritts geändert hat, schlägt der Test fehl, und JUnit Alarm.

Der Tester oder Entwickler kann sich dem erstellten PDF-Report bedienen, um die konkreten Unterschiede zu sehen und einzuschätzen. Beispielhaft wurde dem Titel auf der zweiten Webseite das Wort “Informatik” angehängt. Der Report zeigt neben den beiden verglichenen Screens auch deren Differenz an, wodurch eine schnelle Beurteilung der Unterschiede erleichtert wird:

- 41 -


Bei der Entwicklung grosser Webauftritte, welche hunderte bis tausende unterschiedliche Webseiten beinhalten, kann mit Hilfe einer solchen Regressionstest-Strategie mit wenig Aufwand dem entstehen neuer Darstellungsfehler in verschiedenen Client-Konfigurationen entgegengetreten werden.

3.3.3 Verfügbarkeit Screencompare ist quelloffen und kann über Google Code bezogen werden: http://code.google.com/p/screencompare/ Neben den Quellen steht ein Paket “screencompare.zip” zur Verfügung, welches die Testausführung und -entwicklung mit möglichst geringem Aufwand ermöglichen soll. Darin sind alle benötigten Bibliotheken, einige Beispiel-Tests sowie zwei Skripten zum Ausführen von Tests auf der Kommandozeile enthalten. Auf Google Code findet sich ausserdem ein “Getting Started” 93-Dokument (englisch), welches die ersten Schritte erläutert und auf einzelne Beispiel-Tests eingeht.

Zusammenfassung Testen ist als integraler Bestandteil der Softwareentwicklung akzeptiert. In modernen Entwicklungsmodellen ist diese Disziplin zentral verankert. Gleichzeitig kommen speziell im Web-Bereich eine Vielzahl kleiner bis mittelgrosser Projekte ohne jegliche Testautomatisierung aus. Dies scheint einerseits mit dem strukturell komplexen Technologiemix, und andererseits mit teilweise unausgereiften und damit aufwändig zu implementierenden Testkonzepten zusammenzuhängen. In dem momentan sehr dynamischen Feld der Webtechnologien und der darauf aufbauenden Frameworks gibt es allerdings viele Bestrebungen nach einfacher Testbarkeit und technologieübergreifenden Lösungen94 . Aus meiner eigenen Erfahrung in der Webentwicklung komme ich zum Schluss, dass die Testbarkeit möglichst aller Aspekte einer Webanwendung erstrebenswert ist, wobei die Anforderungen verschiedener Projekte jeweils unterschiedliche Ansätze verlangen. Die kurzen Entwicklungszyklen in diesem Bereich sprechen fast immer für die Automatisierung des Testarsenals, wobei anforderungsübergreifende Werkzeuge wünschenswert sind, um den Testaufwand gering zu halten.

93 94

http://code.google.com/p/screencompare/wiki/GettingStarted [7.9.2010] Vgl. Abschnitt 2.5 oder Test-Werkzeuge in Frameworks wie dem Zend Framework, GWT oder Wt - 42 -


Mit Screencompare ist ein Prototyp f端r automatisiertes Layout-Testen auf visueller Ebene entstanden. Dieser kann hoffentlich als Inspiration dienen und Entwicklern helfen, die entsprechende Anforderungen pr端fen m旦chten. Durch seinen modularen Aufbau ist Screencompare einfach erweiterbar und kann f端r die Verwendung in verschiedensten Projekten angepasst werden.

- 43 -


Quellen Abbildungen 1. Pätzold, Michael (2010): V-Modell.svg. http://de.wikipedia.org/w/index.php?title=Datei:VModell.svg&filetimestamp=20100126152418 [7.9.2010] 2. Memon, Atif M.; Pollack, Martha E.; Soffa, Mary L. (1999): Using a goal-driven approach to generate test cases for GUIs. Proceedings of the 1999 International Conference on Software Engineering, S. 264. http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=841016 [7.9.2010] 3. Franke, Gerd (2006): Webanwendung client server 01.png. http://de.wikipedia.org/w/ index.php?title=Datei:Webanwendung_client_server_01.png&filetimestamp=20070603211516 [7.9.2010] 4. Deken, Jean M.: Documentation of the Early Web at SLAC. http://www.slac.stanford.edu/ history/earlyweb/firstpages.shtml [7.9.2010] 5. Selbst erstellt 6. Manuel (2010): Screenshots. http://phpundercontrol.org/screenshots.html [7.9.2010] 7. Selbst erstellt 8. Selenium Remote Control. http://seleniumhq.org/projects/remote-control/ [7.9.2010] 9. Theme for the LWIS.net CSS Drop-Down Menu. http://www.lwis.net/free-css-drop-down-menu/ dropdown.mtv.com.html [7.9.2010] 10. Smile Designer Smile. http://9elements.com/io/?page_id=54 [7.9.2010] 11. Fowler, Martin: Xunit. http://www.martinfowler.com/bliki/Xunit.html [23.9.2010] 12. Selbst erstellt 13. Selbst erstellt

Literatur • 1998: IEEE 829-1998 Software Test Documentation. http://ieeexplore.ieee.org/xpls/abs_all.jsp? arnumber=4578383 [7.9.2010] • 1987: IEEE 1008-1987 Software Unit Testing. http://ieeexplore.ieee.org/xpls/abs_all.jsp? arnumber=27763 [7.9.2010] • 2004: IEEE 1012-2004 Software Verification and Validation. http://ieeexplore.ieee.org/xpls/ abs_all.jsp?arnumber=1488512 [7.9.2010] • 2008: IEEE 1028-2008 Software Reviews and Audits. http://ieeexplore.ieee.org/xpls/abs_all.jsp? arnumber=4601584 [7.9.2010] • ISO/IEC 29119 (Entwurf). http://softwaretestingstandard.org [7.9.2010] • Version 6.3: BS 7925-1. http://www.testingstandards.co.uk/bs_7925-1_online.htm • Komponententest. http://de.wikipedia.org/wiki/Komponententest [7.9.2010] • Integrationstest. http://de.wikipedia.org/wiki/Integrationstest [7.9.2010] • Regressionstest. http://de.wikipedia.org/wiki/Regressionstest [7.9.2010] - 44 -


• Beck, Kent (1999): Embracing change with extreme programming. Computer, 32/10. http:// ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=796139 [7.9.2010] • Chung, Lawrence; Leite, Julio C. S. P. (2009): On Non-Functional Requirements in Software Engineering. Lecture Notes in Computer Science, 5600. http://www.springerlink.com/content/ l8p285p273461j60/ [23.9.2010] • Corry, Michael D.; Frick, Theodore W.; Hansen, Lisa (1997): User-Centered Design and Usability Testing of a Web Site: An Illustrative Case Study. Educational Technology Research and Development, 45/4. http://www.springerlink.com/content/8075186635071u92/ [7.9.2010] • Crockford, Douglas (2008): The World's Most Misunderstood Programming Language Has Become the World's Most Popular Programming Language. http://javascript.crockford.com/ popular.html [23.9.2010] • Dixon, Eleri; Enos, Emily; Brodmerkle (2006): A/B Testing. US Patent Application Publication, US 2006/0162071 A1. http://ip.com/patapp/US20060162071 [23.9.2010] • Elmendorf, William (1967): Evaluation of the Functional Testing of Control Programs. http:// benderrbt.com/Evaluation%20of%20the%20Functional%20Testing%20of%20Control %20Programs%20-%201967.pdf [7.9.2010] • Fowler, Martin (2006): Continuous Integration. http://martinfowler.com/articles/ continuousIntegration.html [7.9.2010] • Gamma, Erich; Beck, Kent (1999): JUnit: A cook's tour. http://www.redbrick.dcu.ie/~deviant/files/ Renaat/testing/cookstour.pdf [7.9.2010] • Gelperin, David; Hetzel, Bill (1988): The growth of software testing. Communications of the ACM, 31/6. http://portal.acm.org/citation.cfm?id=62959.62965 [7.9.2010] • Hoffman, Douglas (1999): Cost Benefits Analysis of Test Automation. http:// www.softwarequalitymethods.com/Papers/Star99%20model%20Paper.pdf [7.9.2010] • Meerts, Joris; Graham, Dorothy: The Annotated History of Software Testing. http:// www.testingreferences.com/testinghistory.php [7.9.2010] • Melnik, Grigori; Meszaros, Gerard (2009, RC1): Acceptance Test Engineering Guide, Vol. I. http://testingguidance.codeplex.com/ [7.9.2010] • Memon, Atif M.; Pollack, Martha E.; Soffa, Mary L. (1999): Using a goal-driven approach to generate test cases for GUIs. Proceedings of the 1999 International Conference on Software Engineering. http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=841016 [7.9.2010] • Neystadt, John (2008). Automated Penetration Testing with White-Box Fuzzing. http:// msdn.microsoft.com/en-us/library/cc162782.aspx [23.9.2010] • Runeson, Per (2006): A Survey of Unit Testing Practices. IEEE Software, 23/4. http:// doi.ieeecomputersociety.org/10.1109/MS.2006.91 [23.9.2010]

- 45 -


• Takeuchi, Hirotaka; Nonaka, Ikujiro (1986): The new new product development game. Harvard Business Review. https://www.iei.liu.se/fek/frist/723g18/articles_and_papers/1.107457/ TakeuchiNonaka1986HBR.pdf [7.9.2010] • Wack, John; Tracy, Miles; Souppaya, Murugiah (2003): Guideline on Network Security Testing. NIST Special Publication, 800-42. http://csrc.nist.gov/publications/nistpubs/800-42/NISTSP800-42.pdf [23.9.2010] • Yang, Ji-Tzay; Huang, Jiun-Long; Wang, Feng-Jian (1998): A Tool Set to Support Web Application Testing. http://dspace.lib.fcu.edu.tw/jspui/bitstream/2377/2111/1/ ce07ics001998000155.pdf [7.9.2010]

- 46 -

Peacock Magazine Vol.1  

Test version

Read more
Read more
Similar to
Popular now
Just for you