Für den vielleicht ungewöhnlichen Ratschlag, möglichst wenige Testfälle über die grafische Benutzeroberfläche zu automatisieren, gibt es handfeste Gründe, die im folgenden Beitrag dargestellt werden. Im Anschluss daran: eine gute Strategie für Testautomatisierung. Nach der Präsentation verschiedener Testautomatisierungsarchitekturen wird schließlich erläutert, welche dieser Architekturen jene mit dem meisten Potenzial für wartbare und robuste Testfälle sind. [...]
HERAUSFORDERUNGEN
Automatisierte Tests können verschiedene Schnittstellen verwenden, um mit dem zu testenden System zu interagieren. Die sehr oft favorisierte, aber meist auch die schwierigste Schnittstelle bei System- und Abnahmetests ist die grafische Benutzeroberfläche (GUI). Die damit verbundenen Herausforderungen können in folgende drei Gruppen unterteilt werden:
- Verzögerte Information bei Änderungen am zu testenden System: Testwerkzeuge verwenden Techniken wie Reflection, Window Messages, Programmierschnittstellen (Microsoft MSAA, UIA) oder Bilderkennung, um mit dem GUI zu interagieren. Folglich kann das Testwerkzeug bzw. der Compiler Änderungen im GUI nicht erkennen. Erst während der Testdurchführung treten Probleme auf. Ein weiterer Aspekt dabei ist, dass die GUI-Testautomatisierung oft zeitlich und organisatorisch weit entfernt von der Entwicklung stattfindet. Um diesen Problempunkt zu reduzieren, ist ein gut funktionierendes Änderungsmanagement erforderlich. Auch moderne Prozessansätze wie die agile Entwicklung versuchen, diese Distanz zu mindern.
- Technische Herausforderungen: Testwerkzeuge funktionieren meist gut mit Standardsteuerelementen. Vielfach sind aber auch selbst entwickelte oder von Drittanbietern erworbene Steuerelemente im Einsatz. Will man nicht auf unrobuste Workarounds ausweichen, muss man die Steuerelemente durch Anpassung des Quellcodes testbar machen. Drittanbieter stellen jedoch häufig den Quellcode nicht zur Verfügung. Auch die Synchronisation zwischen GUI und automatisierten Testfällen stellt ein Problem dar. Denn manchmal dauert es etwas länger, bis eine Tabelle vollständig mit Daten gefüllt ist oder das Testwerkzeug zum gewünschten Steuerelement vordringen kann.
- Aufwand für robuste Testfälle: Ein unerwarteter, für die Testbedingung aber unwesentlicher Dialog (z.B. ein Update-Hinweis des Antivirenprogramms) hat schon so manchen Testautomatisierer zur Verzweiflung gebracht. Ein oft noch größeres Problem ist es, für jeden Testfall wieder einen definierten Anfangszustand herzustellen. Auch nach einem Fehler muss für den folgenden Testfall dieser Zustand garantiert werden. GUI-Tests sind überwiegend Systemtests. Folglich ist es meist nicht so leicht, sich von Fremdsystemen, Sensoren oder Datenbanken zu entkoppeln. In niedrigeren Teststufen wäre das durch „Mocks“ einfacher umzusetzen.
STRATEGIE FÜR DIE TESTAUTOMATISIERUNG
Lisa Crispin und Janet Gregory stellen in ihrem vielfach verkauften Buch „Agile Testing – A Practical Guide for Testers in Agile Teams“ eine Testpyramide vor. Komponententests (engl. „Unit Tests“ – also Tests von Klassen und Methoden) bilden die breite Basis der Testpyramide. Implementiert der Entwickler die Tests während oder im besten Fall vor dem Code (testgetriebene Entwicklung), entsteht automatisch testbarer Code. Diese Vorgehensweise verringert den Aufwand für die Testautomatisierung beträchtlich. Ein weiterer Vorteil ist die rasche und häufige Rückkopplung zum Entwickler mit Informationen über mögliche Fehler.
Dienste (z.B. Web Services) und Programmierschnittstellen (API) bilden die zweite Schicht in der Testpyramide. Sie sind deswegen überwiegend leicht automatisierbar, da es meist keinen Medienbruch zwischen getesteter Applikation und Testautomatisierung gibt. Die betrachteten Systemteile lassen sich zumeist auch leichter von der Außenwelt isolieren.
Das Ganze ist mehr als die Summe seiner Teile. Diesen Lehrsatz von Aristoteles muss auch bei der Teststrategie berücksichtigt werden. Folglich sind auch System- und Abnahmetests (und damit auch GUI-Tests) nötig. Sie bilden aber nur die Spitze in der Testpyramide.
AUSWAHL GEEIGNETER TESTS
Besonders bei der Testautomatisierung über die GUI sollte selektiv bei der Auswahl geeigneter Testfälle vorgegangen werden. Es kann folgendes einfaches aber effektives Modell angewendet werden.Dabei ermittelt man für jeden Testfall den Wert und den Aufwand für die Testautomatisierung und stellt die beiden Attribute anschließend in einem Diagramm gegenüber.
Unter anderem können folgende Faktoren verwendet werden, um den Wert eines Testfalls zu ermitteln:
- Risiko: Dieses ist das Produkt aus Wahrscheinlichkeit des Auftretens eines Ereignisses und der Schwere der Auswirkungen.
- Verwendungshäufigkeit: Eine für den Tagesbetrieb notwendige Funktion ist häufig wichtiger, als eine alle paar Monate benötigte Funktion.
- Fehlerhäufigkeit in der Vergangenheit: Fehler sind wie Pilze, sie treten meist in Gruppen auf, und der größte Teil befindet sich unsichtbar „im Boden“. Testen Sie also Funktionen, die in der Vergangenheit fehlerträchtig waren, intensiver und häufiger.
- Einfluss des getesteten Prozesses auf den Erfolg der Organisation.
Der Aufwand für die Testautomatisierung ist die zweite Messlatte für die Auswahl geeigneter Tests. Einfluss auf diesen Faktoren haben etwa folgende Aspekte:
- Testumgebung bereitstellen
- Testdaten bereitstellen
- Anzahl der schwer testbaren Steuerelemente
- Test automatisieren
- Ergebnisse analysieren
Durch Gegenüberstellung von Wert und Aufwand kann die Implementierungsreihenfolge der Tests ermittelt werden: Demnach sollen Tests mit hohem Wert und niedrigem Aufwand als erstes automatisiert werden. Tests mit niedrigem Wert und hohem Aufwand sollen erst zum Schluss bzw. gar nicht automatisiert werden.
Eine nachvollziehbare Auswahl der Testfälle ist auch aufgrund eines anderen Aspekts wichtig: Menschen suchen nach Herausforderungen. Folglich sind herausfordernde Testfälle, also jene mit hohem Aufwand, für die Testautomatisierer meist interessanter als einfache 08/15-Testfälle. Den Testautomatisierern sollte also eine klare Reihenfolge vorgegeben werden.
ARCHITEKTUREN
Nachdem dargestellt wurde, dass die GUI diejenige Schnittstelle mit den größten Herausforderungen ist und gezeigt wurde, wie geeignete Testfälle ermittelt werden können, wird in diesem Abschnitt die Testautomatisierung näher betrachtet. Dazu gibt es verschiedene Architekturen. Die Wahl der richtigen Architektur hat beträchtliche Auswirkungen auf den Erfolg der Testautomatisierung. Automatisierte Testfälle sollen folgende Qualitätsattribute erfüllen:
- Robust: Kleine Änderungen in Steuerelementen (z. B. ID, Position) dürfen sich nicht auf die automatisierten Tests auswirken. Des Weiteren sollen Tests trotz unerwarteter, aber für den Test unwesentlichen Ereignisse weiterlaufen. Jeder Test muss am Beginn der Durchführung auf einen definierten Systemzustand vertrauen können.
- Wartbar: Änderungen im GUI dürfen nur einen geringen Wartungsaufwand verursachen.
- Lesbar: Testspezifikation und Testprotokolle sollen für die Zielgruppe lesbar sein.
Um diese Qualitätsattribute umsetzen zu können, unterscheidet man zwischen drei Abstraktionsschichten, die zwischen der Testspezifikation und dem getesteten System liegen:
- Die unterste Schicht ist die Technik. Sie befasst sich mit der Identifikation von grafischen Steuerelementen und wie diese Informationen abgelegt und wiederverwendet werden können.
- Workflows bilden die mittlere Schicht. Wiederkehrende Abläufe sollen in möglichst vielen Testfällen Anwendung finden.
- Die oberste Schicht bildet die Präsentation der Testfälle. Sie wird nur benötigt, wenn automatisierte Tests auch von Personen zusammengestellt werden sollen, die nicht programmieren können.
Nachfolgend werden mögliche Testautomatisierungsmodelle basierend auf dieser Schichtenarchitektur beschrieben:
- Capture & Replay funktioniert nicht! Obwohl diese Aussage durch viele fehlgeschlagene Testautomatisierungsprojekte untermauert wird, ist es genau diese Methode, die manche Werkzeughersteller am meisten bewerben. Das Problem ist, dass die Testfälle zu eng mit der grafischen Benutzeroberfläche verwoben sind. Technische Informationen für die Erkennung von Steuerelementen werden nicht zentral, sondern im schlechtesten Fall in jedem Testfall separat abgespeichert. Änderungen in der GUI verursachen dadurch hohen Wartungsaufwand.
- Beim „Scripting“ wird versucht, häufig verwendete Abläufe in mehreren Testfällen wiederzuverwenden. Die meisten Werkzeughersteller kombinieren Scripting mit einer Map (was als „klassische Kombination“ bezeichnet werden kann). In der Map werden alle Informationen, die zur Identifikation von Steuerelementen benötigt werden, an einer zentralen Stelle abgelegt. Testfälle und Scripts sollen keine solchen Informationen mehr enthalten, sondern diese aus der Map beziehen. Ändert sich ein Steuerelement (z. B. der Name), ist idealerweise nur eine Änderung in der Map nötig, um mehrere von der Änderung betroffene Testfälle wieder zum Laufen zu bringen.
- „Keyword-Driven Testing“ ermöglicht es auch Nichttechnikern, Testfälle zusammen zu stellen. In eigens dafür entwickelten Editoren (teilweise wird auch Excel dafür verwendet) können Tester die Bausteine (Keywords, generische Aktionen) zu neuen Testfällen kombinieren. Die Bausteine selbst werden typischerweise von Personen mit Programmierkenntnissen erstellt und bereitgestellt.
- Eine neuere und interessante Architekturvariante für die Testautomatisierung ist das „Page Object Pattern“ kombiniert mit Workflows. Page Objects ersetzen die Map, indem sie die Informationen, die zur Identifikation von Steuerelementen nötig sind, in Einheiten kapseln, welche auch der Benutzer wahrnimmt: in Fenstern. Demnach existiert für jedes Fenster genau ein Page Object. Testfälle und Workflows dürfen nur mehr über die Page Objects auf die GUI zugreifen. Die Page Objects bieten den oberen Schichten der Testautomatisierung praktische Methoden an, wie z. B. die Arbeit mit Tabellen. Außerdem können sie die Testautomatisierung von mehrsprachigen Systemen unterstützen, sowie die Protokollierung und die Interaktion mit komplizierten Steuerelementen. Fortgeschrittene Testautomatisierer generieren Page Objects, was besonders bei größeren Systemen mit hunderten von Fenstern viel Zeit erspart. Der alternative Weg, Page Objects manuell zu programmieren, ist aber bei vielen Systemen vertretbar.
- Wie der Name „Specification by Example“ erkennen lässt, dient diese Architektur dazu, gemeinsam mit dem Kunden Beispiele zu spezifizieren. Die Beispiele dienen allen Akteuren zum besseren Verständnis des Problems und dem Entwicklungsteam als Testfälle. Der Fokus bei dieser Architektur liegt klar auf der Schicht „Präsentation“. Nichttechniker sollen Beispiele und somit Testfälle schreiben und lesen können. Beispiele für Systeme, die diese Architektur nutzen, sind FitNesse (http://fitnesse.org) und Programme für Behaviour-Driven Development (z.B. JBehave, http://jbehave.org). Es ist zu empfehlen, diese Architektur jedoch primär für Abnahme- und Akzeptanztests zu verwenden. Bei Systemtests ist oft keine Lesbarkeit für Nichttechniker erforderlich. Page Objects und Workflows reichen hier aus und Sie ersparen sich die Wartung einer Präsentationsschicht.
AUSWAHL DES WERKZEUGES
Die Testautomatisierung stellt besondere Anforderungen an die Mitarbeiter und die Werkzeuge. Es gibt zwei Aspekte, die jedenfalls berücksichtigt werden sollten:
- Capture & Replay funktioniert nicht.
- Testautomatisierung ist in vielen Bereichen Softwareentwicklung.
Wenn schon Capture & Replay eingesetzt wird, dann sollte zumindest darauf geachtet werden, dass das verwendete Werkzeug auch die Möglichkeit bietet, die damit generierten Scripts durch eigene Programmierung zu erweitern. Somit sollen robuste und wartbare Tests implementiert werden können. Durch Trennung der Testspezifikation (Kundensicht) von der Testautomatisierung (Sicht der Techniker) können die Fähigkeiten der Mitarbeiter am effizientesten eingesetzt werden.
FAZIT: EIN ERFOLGSREZEPT
Nachfolgend werden einige Punkte aufgelistet, die als Erfolgsrezept für die Testautomatisierung dienen können:
- Auswahl: Testen Sie so wenig wie möglich über die GUI. Wählen Sie die zu automatisierenden Tests sorgfältig aus.
- Architektur: Verwenden Sie Page Objects und Workflows. Programmieren Sie Testfälle in einer weit verbreiteten Allzwecksprache, wie Java oder C#. Wenn es für die Kommunikation mit dem Kunden hilfreich ist, kann eine zusätzliche Präsentationschicht für einen Teil der Tests sinnvoll sein.
- Identifikation von Steuerelementen: Verwenden Sie eine Programmbibliothek, bei der Steuerelemente über XPath identifiziert werden und das Page Object Pattern umgesetzt werden kann.
- Entwicklungsumgebung: Werkzeuge wie Eclipse und Visual Studio erhöhen die Effizienz beim Automatisieren von Tests.
- Programmieren: Testfälle sollen primär von Personen automatisiert werden, die programmieren können.
* Johannes Hochrainer ist seit 2006 bei Software Quality Lab als Unternehmensberater und Trainer beschäftigt. Seine Erfahrung im Bereich Testmanagement und Testautomatisierung resultiert aus rund 30 Projekten pro Jahr.
Be the first to comment