Welche Stufen kennt das Testdesign in der Testautomatisierung?
Testautomatisierung hat das Ziel, die Effizienz beliebiger Testaktivitäten zu steigern. Das beginnt schon beim Testentwurf. Auch das Testdesign in der Testautomatisierung lässt sich unterschiedlich weit automatisieren, in fünf Stufen mit verschiedenen Ansätzen:
- Capture & Replay
- Skriptbasiert
- Datengetrieben
- Schlüsselwortgetrieben
- Modellbasiert
Mit jeder Stufe steigt der Anspruch an den Testentwurf. Capture & Replay liefert schneller Ergebnisse, schlüsselwort- und modellbasierte Techniken senken dafür den Wartungsaufwand auf Dauer und wachsen mit dem Testumfang mit.
Welche Testfälle ein Testobjekt braucht, leiten Testentwurfsverfahren ab, etwa der Entscheidungstabellen- oder der Zustandsübergangstest. Die fünf Stufen setzen danach an. Sie legen fest, in welcher Form ein Testfall vorliegt und wie viel Arbeit ein Werkzeug übernimmt.
Der Testentwurf braucht bei automatisierten Tests so viel Aufmerksamkeit, weil sich Software ständig ändert, mal häufiger, mal seltener. Geänderte Anforderungen oder entdeckte Fehler ziehen Anpassungen an den Testskripten nach sich. Ändert sich die Software oft, frisst der manuelle Wartungsaufwand für die Testskripte den Vorteil der automatischen Testdurchführung schnell auf.
Capture & Replay: schnell aufgezeichnet, teuer gepflegt
Capture & Replay ist die Einstiegsstufe. Sie ist sehr günstig im Start und sehr teuer im Betrieb, weil jede Änderung am System eine neue Aufzeichnung verlangt.
Bei Capture & Replay zeichnet ein Werkzeug die manuelle Ausführung eines Testfalls auf (capture) und spielt diese Aufzeichnung beliebig oft wieder ab (replay). Dafür braucht es Testwerkzeuge, die die Handlungen des Testers mitschneiden und danach an der Schnittstelle des Testobjekts wiederholen. Dieser Anspruch an das Werkzeug wächst mit der Komplexität des Testobjekts. Im Extremfall kommen Testroboter zum Einsatz, die z.B. Hardware-Komponenten hinzufügen, ändern oder entfernen. Im einfachsten und häufigsten Fall testet das Werkzeug über die Bedienung und Beobachtung eines Webbrowsers. Für die Aufzeichnung muss es nur die Aktionen von Maus und Tastatur auf der Oberfläche speichern, dazu Position und Inhalt der erwarteten Reaktionen.
Dafür gibt es zwei Möglichkeiten: Das Werkzeug speichert die absoluten Koordinaten aller Mausklicks oder die Objekt-IDs der angeklickten Elemente, sofern es welche gibt. Mit Objekt-IDs muss niemand die Testfälle neu aufzeichnen, nur weil sich die Anordnung der Oberflächenelemente ändert. Einer der bekanntesten Vertreter für Capture-&-Replay-Tests von Web-Anwendungen ist Selenium. Die Browser-Erweiterung Selenium IDE zeichnet z.B. in Firefox oder Chrome auf, die Aufzeichnungen laufen danach auf vielen verbreiteten Browsern.
Mit Selenium lassen sich auch die höheren Entwurfsstufen umsetzen. Das ist sogar die Regel.
Der große Vorteil von Capture & Replay: Fachexperten erstellen Testfälle und führen sie aus, ohne Unterstützung von Test- oder Software-Experten und ohne große Vorbereitungs- oder Einarbeitungszeit. Der Haken ist der hohe Anpassungsaufwand. Ändert sich das zu testende System, muss der Tester den Testfall neu aufzeichnen: bei inhaltlichen Änderungen, bei einer geänderten Reihenfolge der Bedienung oder, in der Variante mit absoluten Koordinaten, schon bei minimalen Änderungen des Seitenlayouts. Schon vergleichsweise kleine Änderungen zwingen also dazu, den Großteil der Testfälle neu zu erstellen.
Weil ein Testfall hier aus der Aufzeichnung einer manuellen Ausführung besteht, heißt jede Neuerstellung: den Testfall noch einmal von Hand ausführen. Eine einzelne Änderung kostet je nach Komplexität des Systems wenig bis mittel viel Aufwand. Da sich das Testobjekt aber oft ändert, summieren sich die Anpassungen, und die Testentwurfskosten steigen stark. Capture & Replay eignet sich deshalb vor allem, wenn man schnell Ergebnisse zeigen möchte, wenn Änderungen am System die Ausnahme bleiben oder als Ergänzung zu den folgenden Ansätzen.
Was bringt skriptbasierte Testautomatisierung gegenüber Capture & Replay?
Eine Stufe höher bleiben die initialen Kosten niedrig, die wiederkehrenden sinken auf mittel. Testfälle lassen sich ändern, ohne sie neu auszuführen. Dafür muss jemand im Team programmieren können.
In der skriptbasierten Testautomatisierung entwirft der Testdesigner Testfälle als ausführbare Skripte, also als ausführbaren Testcode. Dafür braucht er Programmierkenntnisse und eine Entwicklungsumgebung. Die Programmiersprache ist frei wählbar. Auf Komponentenebene sind xUnit-Tests verbreitet: Unit-Tests in derselben Sprache x wie das zu testende Programm, für Java also JUnit, für C++ CppUnit usw. Auf Systemtestebene richtet sich die Sprache meist nach der Testschnittstelle des Systems.
Gegenüber Capture & Replay gewinnt der skriptbasierte Testentwurf vor allem eines: Testfalldefinition und Testdurchführung sind voneinander unabhängig. Wer den Testentwurf ändert, muss den Test nicht erneut ausführen, und das zahlt sich besonders bei umfangreichen Tests aus. Die Schwächen ähneln denen von Capture & Replay, denn viele Änderungen erfordern noch immer manuelle Anpassungen an den Testfällen. Sie fallen aber seltener an, weil sich etwa verschobene Oberflächenelemente mit programmiertechnischen Mitteln vergleichsweise einfach nachziehen lassen. Dazu lagert man die Positionen der abgefragten Oberflächenelemente in eigene Klassen aus.
Eine Änderung zieht also nicht zwangsläufig die erneute Ausführung des gesamten Testfalls nach sich. Man kann abwägen, was aufwendiger ist: den Testcode ohne Testausführung anzupassen oder den Testfall manuell auszuführen und wie bei Capture & Replay automatisch zu protokollieren. Das hängt von der konkreten Situation ab. Unsere Erfahrung zeigt aber, dass bei längeren oder zeitkritischen Tests die manuelle Ausführung deutlich mehr kostet als die Anpassung des Skripts. Dazu kommen Aspekte wie Screenshots in Testfällen oder Daten, die während der Testdurchführung aufwendig entstehen. Auch sie machen die Anpassung des Skripts deutlich einfacher als die erneute Ausführung.
Auch die Fehleranfälligkeit der manuellen Testdurchführung zählt. Das Werkzeug protokolliert jeden Bedienfehler mit, und eine Fehlbedienung kann den Zustand des Systems ungewollt ändern. Dann muss die Aufzeichnung von vorn beginnen, was den Aufwand für Capture & Replay weiter erhöht. Unterm Strich überwiegen damit die Vorteile des skriptbasierten Ansatzes.
Was ändert sich beim datengetriebenen Test?
Beim datengetriebenen Test bleibt die Testlogik gleich, und jede neue Zeile mit Werten ist ein weiterer Testfall.
Anders als in den beiden vorherigen Ansätzen stehen beim datengetriebenen Test (data-driven) die Daten im Mittelpunkt. Die Basis ist ein Testentwurf, der von konkreten Daten abstrahiert, z.B. indem er nur die erwarteten Parameter vorgibt, aber nicht deren Werte. Der Tester definiert dann passende Daten, in einem beliebigen Format, das zum verwendeten Framework passt. In der Praxis sind Excel-Tabellen oder SQL-Datenbanken gang und gäbe. Eine Möglichkeit ist eine Tabelle mit je einer Spalte pro Eingabeparameter und pro erwartetem Ausgabeparameter, in deren Zeilen der Tester konkrete Werte einträgt. Ein Adapter verbindet die Tabelle mit dem Testobjekt, übergibt die Eingabeparameter und vergleicht die Ist-Ergebnisse mit den erwarteten Ergebnissen.
Ein typischer Vertreter ist das Testwerkzeug FitNesse, ein Wiki-Webserver, den man lokal auf dem PC installieren kann. Die Daten entstehen direkt als Tabelle auf einer eigenen Test-Wiki-Seite. Alternativ importiert man die Werte im Editiermodus über den Knopf “Spreadsheet to FitNesse” aus einer Excel-Tabelle. Der Knopf “Test” startet die Ausführung. FitNesse färbt jede Zeile grün oder rot, je nachdem, ob das Ist-Ergebnis dem erwarteten Ergebnis entspricht.
Schlüsselwortgetrieben: mehr Vorlauf, weniger Wartung
Hier investiert das Team vorab in eine gemeinsame Sprache aus Schlüsselwörtern und spart später, weil sich viele Änderungen an einer Stelle erledigen lassen.
Die beiden bisher beschriebenen Ansätze basieren auf Programmiersprachen und konzentrieren sich entweder auf Verhalten oder auf Daten. Die nächsten beiden Stufen zielen auf bessere Wartbarkeit durch zusätzliche Abstraktionsebenen.
Im schlüsselwortgetriebenen Testentwurf (keyword-driven) stehen statt konkreter Befehle abstrakte Schlüsselwörter. Eine Adaptionsschicht ersetzt sie zur Laufzeit, je nach Konfiguration, durch konkrete Befehle. Ändert sich das Systemverhalten, ohne dass sich der Sprachumfang ändert, genügt es oft, Schlüsselwörter auszutauschen, und die betroffenen Testfälle sind mit vergleichsweise wenig Aufwand nachgezogen. Viele Teams sehen die bessere Lesbarkeit als wichtigsten Vorteil. Neue Szenarien brauchen trotzdem neue Testfälle, neue Systemaktionen oder -reaktionen neue Schlüsselwörter. Zahlreiche Werkzeuge unterstützen das schlüsselwortgetriebene Testen, und jeder Programmierer kann ein einfaches Framework selbst bauen. Mächtiger sind Werkzeuge mit Editor-Unterstützung, etwa für Auto Completion: Xtext oder Cucumber mit seiner offiziellen IDE-Erweiterung. Bei Xtext legt eine Grammatik die gesamte erlaubte Sprache fest, bei Cucumber tun das die Step-Definitionen.
Der wichtigste Gewinn ist die höhere Abstraktionsebene, mit der sich Testfälle leichter erstellen und warten lassen. Oft ist gar keine umfangreiche Anpassung nötig, weil die Adaptionsschicht die Testfälle ohnehin in konkrete Befehle übersetzt. Viele Änderungen, etwa am konkreten Schnittstellenformat, erledigt das Team einmalig in der Adaptionsschicht, für alle Testfälle gleichzeitig und mit wenig Aufwand. Der Preis ist eine mittlere Komplexität in der Vorbereitung: Die Sprache der Schlüsselwörter und die Aufgaben der Adaptionsschicht muss das Team mit allen Stakeholdern abstimmen.
Technisch lassen sich diese Ergebnisse auch mit dem skriptbasierten Ansatz erreichen. Das verlangt aber viel Vorbereitung, denn die Abstraktionsebenen, etwa Wrapper-Klassen oder Bibliotheken, die Schlüsselwörter in Abfolgen von Aktionen übersetzen, muss das Team selbst schaffen. Außerdem brauchen die Tester Disziplin, um für schnelle Lösungen nicht die höhere Abstraktionsebene zu verlassen und schwer wartbare Testskripte zu hinterlassen. Modellierungsframeworks zwingen die Tester dagegen, auf der Modellierungsebene zu bleiben, und halten die Wartbarkeit so dauerhaft hoch. Frameworks wie Xtext erzeugen zudem komfortable Editoren allein aus der Sprachbeschreibung.
Im modellbasierten Ansatz schreibt der Generator die Testfälle
Auf der obersten Stufe kostet das Modell viel in der Erstellung. Danach sind die wiederkehrenden Kosten sehr niedrig, weil ein Testgenerator die Testfälle erzeugt.
Der modellbasierte Testentwurf nutzt Modelle als Basis. Modelle sind abstrakte Beschreibungen beliebiger Artefakte, hier für den Testentwurf. Sie können das Systemverhalten oder das Testverhalten beschreiben. Sie können ein eigenes Testmodell sein oder Teil eines gemeinsamen Test- und Entwicklungsmodells. Sie können deterministisch oder nichtdeterministisch, zeitlos oder zeitbehaftet, diskret, kontinuierlich oder gemischt sein. Sie können Datenfluss, Kontrollfluss oder beides beschreiben, und das Verhalten kann kontinuierlich oder ereignisgesteuert sein. Entsprechend breit sind die Einsatzmöglichkeiten von Modellen im Testentwurf.
Ein Modell beschreibt einzelne Testfälle abstrakt, es kann aber auch ganze Mengen von Testfällen erfassen. Dafür definiert man Verzweigungen, bedingte Anweisungen, Reaktionen auf externe Ereignisse u.v.m. schon auf Modellebene. Ein Modell gibt außerdem einen Überblick über das gesamte System und die wechselseitigen Abhängigkeiten seiner Komponenten. Das hilft schon in frühen Phasen der Systementwicklung, z.B. beim Review von Anforderungen oder Architekturentwürfen. Und natürlich bündelt das Modell alle testrelevanten Informationen, aus denen dann die Testfälle entstehen.
Leitet ein Generator die Testfälle automatisch aus dem Modell ab, kommen weitere Vorteile dazu. Kleine Änderungen im Modell, die viele Testfälle betreffen, landen automatisch in den Testfällen. Als Endekriterium für den Testentwurf nutzt der Testgenerator oft Qualitätsziele wie eine bestimmte Überdeckung auf Modellebene. So übernimmt er auch Änderungen, die zusätzliche Testschritte, eine andere Zahl an Parametern oder ein geändertes erwartetes Verhalten mit sich bringen. Der Generator erzeugt die betroffenen Testfälle neu.
Ein Beispiel: Eine Anwendung bildet mögliche Karrierepfade mit Prüfungen ab. Es gibt einen direkten Testfall, den Gutfall, in dem jede Prüfung auf Anhieb gelingt. Nimmt man die Schlechtfälle dazu, zeigt schon dieses kleine Beispiel, dass die Schleifen im Modell theoretisch unendlich viele Pfade erlauben. Ein Testgenerator orientiert sich bei der Testerzeugung meist nur an der Struktur des Modells. Kommen Zustände hinzu, ändern sie sich oder fallen sie weg, bezieht er sie beim nächsten automatischen Testentwurf von selbst ein.
Gegenüber dem schlüsselwortgetriebenen Ansatz lässt sich jetzt der gesamte Ablauf beschreiben und für den Testentwurf nutzen, mit Verzweigungen, Schachtelungen, Schleifen und parallelem Verhalten. Ein modellbasierter Testgenerator interpretiert das Modell, erzeugt daraus einzelne kontrollflussbasierte Ablaufsequenzen und wandelt sie in ein vorher definiertes Zielformat um. Gängige Zielformate sind ausführbarer Testcode, eine menschenlesbare Fassung davon, z.B. für die Validierung, und die Testdokumentation. Auf jede Änderung im Modell oder in den Exporten des Testgenerators kann das Team so reagieren, der Generator erzeugt die Testfälle anschließend neu. Die Gefahr, wie in den vorherigen Stufen viele Testfälle mit entsprechendem Aufwand von Hand anpassen zu müssen, entfällt. Die Testeffizienz steigt deutlich. Der Nachteil ist der hohe Vorbereitungsaufwand.
Was die fünf Stufen kosten
Ein qualitativer Vergleich auf Basis unserer Erfahrungen zeigt folgende Kostenstruktur:
| Capture & Replay | Skriptbasiert | Datengetrieben | Schlüsselwort-getrieben | Modellbasiert | |
|---|---|---|---|---|---|
| Initiale Kosten | sehr niedrig | niedrig | niedrig | mittel | hoch |
| Wiederkehrende Kosten | sehr hoch | mittel | mittel | niedrig | sehr niedrig |
Höhere Stufen der Testautomatisierung sparen langfristig Kosten, niedrigere eignen sich besser für eine schnelle Einschätzung. Bei der Wahl zählen außerdem die Rahmenbedingungen: Welches Projektvorgehen gilt? Wer erstellt die Testfälle? Wie viel Kapazität steht bereit? Mehr Anhaltspunkte zur Wahl der richtigen Strategie findest Du in unserem Buch “Basiswissen Testautomatisierung”.
Der ISTQB-Lehrplan Test Automation Engineering (Version 2.0) zeichnet ein ähnliches Bild. Er beschreibt Mitschnitt (Capture/Playback), lineare und strukturierte Skripterstellung sowie datengetriebenes und schlüsselwortgetriebenes Testen als Ansätze, um Testfälle zu automatisieren. Den Mitschnitt hält er nur bei kleinem Umfang und einem System, das sich selten ändert, für machbar. Modellbasierte Werkzeuge ordnet er der Testgenerierung zu, also dem automatisierten Entwurf von Testfällen aus einem Testmodell.
Häufig gestellte Fragen
Welche Werkzeuge passen zu welcher Stufe der Testautomatisierung?
Für Capture & Replay von Web-Anwendungen ist Selenium einer der bekanntesten Vertreter, die Aufzeichnung übernimmt die Browser-Erweiterung Selenium IDE. Skriptbasierte Tests entstehen auf Komponentenebene oft mit xUnit-Frameworks wie JUnit oder CppUnit. FitNesse trägt den datengetriebenen Test über Tabellen in einem Wiki. Für schlüsselwortgetriebene Tests gibt es Xtext oder Cucumber.
Nach welchen Kriterien wählt ein Team die Stufe für sein Testautomatisierungskonzept?
Nach den Rahmenbedingungen des Projekts: welches Projektvorgehen gilt, wer die Testfälle erstellt und wie viel Kapazität bereitsteht. Mit Capture & Replay kommen Fachexperten ohne Unterstützung von Software-Experten schnell zu Ergebnissen. Ab der skriptbasierten Stufe braucht das Team Programmierfähigkeiten. Schlüsselwortgetriebene Ansätze verlangen Abstimmung mit allen Stakeholdern, modellbasierte einen hohen Vorbereitungsaufwand.
Welche Stufe eignet sich für die Testautomatisierung von Software, die sich häufig ändert?
Je häufiger sich die Software ändert, desto eher lohnt eine höhere Stufe. Beim schlüsselwortgetriebenen Ansatz lassen sich viele Änderungen einmalig in der Adaptionsschicht nachziehen. Im modellbasierten Ansatz erzeugt der Testgenerator die betroffenen Testfälle neu. Capture & Replay verlangt bei jeder Änderung eine neue Aufzeichnung und passt nur, wenn Änderungen die Ausnahme bleiben.


