Web-Anwendungen effektiv testen
Artikel erschienen in Swiss IT Magazine 2008/20
Die Forderung nach qualitativ hochwertiger und auch wartbarer Software setzt eine enge Verknüpfung von Entwicklung und Tests (wie in der Test-getriebenen Entwicklung) voraus. Testansätze, wie sie manchen noch aus dem Wasserfall-Modell bekannt sind, wo zunächst die Implementierung erfolgt und dann am Ende die Anwendung getestet wird, entsprechen in keinster Weise mehr den Anforderungen an zeitgemässe Software-Entwicklung, insbesondere bei kurzen Release-Zyklen oder Web-Applikationen, die gar keine Versionen mehr im klassischen Sinn kennen.
Auch vereinfachen sie die Entwicklung in Teams, da die Auswirkungen von einzelnen Änderungen über das ganze Projekt einfacher gebändigt werden können. Daher ist es nicht nur wesentlich, dass eine hinreichende Zahl an Tests vorhanden ist, sondern vor allem, dass diese im Rahmen einer Build-Automatisierung (z.B. über Werkzeuge für Continuous Integration) sowie in der IDE des Entwicklers einfach und automatisiert ausgeführt werden können. Dies ist bei Tests niedriger Granularität wie Unit-Tests noch relativ einfach machbar. Möchte man jedoch Anwendungen oder Services, die übers Internet angeboten werden, automatisiert testen, so steigen die Anforderungen an Testumgebung und Tools deutlich an. Auch reichen bei Client/Server-Systemen rein funktionale Tests nicht mehr aus: Es muss gewährleistet werden, dass die Anwendung die Performance-Anforderungen erfüllt!
Zunächst muss man hier zwischen zwei sehr unterschiedlichen Arten von Tests unterscheiden: Bei funktionalen Tests versucht man festzustellen, ob sich die Anwendung verhält, wie man das erwartet. Bei einer Webanwendung muss das Werkzeug automatisiert Seiten aufrufen, Formulare ausfüllen, mit JavaScript interagieren sowie überprüfen können, ob die Ergebnisse den Erwartungen entsprechen.
Bei Last-Test steht zunächst eine andere Frage im Vordergrund: Ist die Webanwendung (oder auch der Webservice) in der Lage, mit der erwarteten Last an Benutzeranfragen umzugehen, und ab wann kann der Server die Anfragen nicht mehr mit hinreichender Geschwindigkeit beantworten? Denn wenn man Load-Balancing-Strategien plant, sollten sie auf ihre Effektivität hin getestet werden.
Apache JMeter erlaubt das Testen beliebiger Webanwendungen. Es unterstützt sowohl funktionale- als auch Last-Tests, wobei JMeter wohl am ehesten bei einer Kombination dieser beiden Tests seine Stärken ausspielen kann. Um einen Test mit JMeter zu definieren, ist es zunächst am einfachsten, die graphische Benutzerschnittstelle zu verwenden. Ein wichtiger Tipp an dieser Stelle: Setzten Sie die Sprache im jmeter.properties auf Englisch (lang=en), denn die deutsche Übersetzung ist nicht gelungen und verwirrt mehr, als dass sie nützt.
Zuerst gilt es, einen Testplan zu definieren. In diesen Testplan können je nach Anforderung des Tests verschiedene Komponenten inkludiert werden. JMeter ermöglicht hier die Definition von Thread Groups. Damit kann definiert werden, wie viele «parallele» Benutzer JMeter simuliert, sowie wie viele Anfragen in Serie ausgeführt werden sollen.
In einem Testplan können unter anderem folgende Komponenten verwendet werden:
Möchte man rein funktionale Tests machen, so können Bibliotheken wie HTML-, HTTP-Unit oder JWebUnit eine gute Wahl sein. Diese lassen sich auch sehr einfach in automatisierte Testumgebungen wie Maven, Continuum oder Hudson integrieren.
Im Gegensatz zu JMeter verfügen diese Bibliotheken nicht über ein GUI, sind aber sehr gut in eigene Java-Testumgebungen zu integrieren. Im Prinzip arbeiten alle drei Werkzeuge ganz ähnlich. Die HTMLUnit-Webseite bezeichnet ihr Tool als «Browser für Java-Anwendungen». Im Zusammenspiel mit Test-Frameworks wie JUnit lassen sich damit recht einfach funktionale Tests von Webanwendungen erstellen. HTMLUnit vereinfacht dabei den Zugriff auf Webseiten (dabei kann z.B. angegeben werden, als welcher Browser man sich zu erkennen geben möchte) und erlaubt das einfache Navigieren in den zurückgesendeten HTML-Dokumenten. Auch die Interaktion mit Formularen ist über die API kein Problem.
Wie man sieht, findet sich im Open-Source-Umfeld eine Reihe von Werkzeugen, die das automatisierte Testen von Webanwendungen vereinfachen – wobei Apache JMeter sogar allgemein Anwendungen, die Services über Netzwerkprotokolle anbieten, testen kann. JMeter ist dabei ein Vertreter, der sich vor allem auf die Kombination von funktionalen- und Last-Tests gut anwenden lässt. Der Lernkurve bei JMeter ist allerdings speziell bei Einstieg relativ steil und die Bedienung leider nicht immer intuitiv. Man braucht Zeit, um zu verstehen, was das Werkzeug macht, und um es dazu zu bringen, die Tests in der Weise auszuführen, die zu den Anforderungen passt.
HTML-Unit beziehungsweise JWebUnit sind im Gegensatz dazu sehr schnell und einfach zu verstehen und bieten sich an, wenn man funktionale Tests in Java schreiben möchte, die sich leicht in die anderen Unit-Tests eines Projektes integrieren und sich auch sehr leicht in bestehende Automatisierungs- oder Continuous-Integration-Lösungen einbinden lassen.
Alexander Schatten (alexander@schatten.info) ist Assistent am Institut für Softwaretechnik und interaktive Systeme der Technischen Universität Wien.