Blog Testautomatisierung mit der Test Workbench

Testautomatisierung mit der Test Workbench

Testgetriebene Entwicklung geh├Ârt bei n-design zum Alltag. Hierbei kommt die ├╝bliche Toolchain bestehend aus JUnit, Maven (Surefire Plugin) und Jenkins zum Einsatz. Damit erreichen wir eine hohe Testabdeckung im Bereich der Komponententests und k├Ânnen eine gro├čen Teil von Integrationstests umsetzen.

F├╝r die Durchf├╝hrung von Systemtests kommen zus├Ątzlich unterschiedliche Werkzeuge, z.B. Selenium f├╝r Web-GUI-Tests oder SOAP-UI f├╝r WebServices, zum Einsatz. Diese eher lose Tool-Sammlung ist f├╝r eine begrenzte Menge an explorativen Tests und seltene Deployments beherrschbar. Das wird allerdings schnell anders, wenn die Zahl der Tests steigt und diese h├Ąufig oder regelm├Ą├čig ausgef├╝hrt werden sollen.

Im Rahmen der Entwicklung einer dezentralen Komponente der Telematikinfrastruktur der gematik, die wir bei n-design betreiben, m├╝ssen hohe Anforderungen an Systemtests erf├╝llt werden, so dass wir dringend eine L├Âsung zur Testautomatisierung finden mussten.

Entwicklung einer eigenen Testautomatisierung

Am Markt sind einige Produkte zur Testautomatisierung verf├╝gbar, die wir entsprechend unserer Anforderungen betrachtet haben. Insbesondere das Test-Framework Citrus hat uns gut gefallen. Allerdings haben wir sehr spezifische Anforderungen bzgl. der Testfall-Definition und des Reportings zu erf├╝llen, so dass die Verwendung eines Standard-Tools mit hohem Aufwand f├╝r das Customizing einhergegangen w├Ąre. Auch das Risiko bestimmte Anforderungen ggf. gar nicht umsetzen zu k├Ânnen, erschien uns letztlich gr├Â├čer als das einer Eigenentwicklung, zumal wir auf einige Projekterfahrung im Bereich Testautomatisierung zur├╝ckblicken k├Ânnen. Wir entschieden uns daher, ein eigenes Tool zur Testautomatisierung zu entwickeln.

Ziele der Test Workbench

Modularisierung von Ausf├╝hrungsschritten - Testmodule

Ziel der Test Workbench ist, bei der Definition von Testf├Ąllen auf Programm Code im Sinne imperativer Programmierung zu verzichten. Ein Testfall besteht jedoch aus ausf├╝hrbaren Komponenten. Diese zu programmierenden Komponenten werden daher in Module gekapselt und k├Ânnen f├╝r einen konkreten Testfall deklarative komponiert werden. Dies hat aus unserer Sicht mehrere Vorteile:

  • Die Wiederverwendung der programmatischen Teile wird vereinfacht.
  • Eine Arbeitsteilung zwischen Entwicklern und Testfall-Designern ist leichter m├Âglich. Testfall-Designer m├╝ssen nicht zwingend Entwickler sein.
  • Module k├Ânnen in beliebiger Reihenfolge zu Ausf├╝hrungssequenzen miteinander kombiniert werden.

Testmodule teilen sich dabei eine gemeinsame einfache Schnittstelle, ├╝ber die jedes Modul die Ergebnisse der Vorg├Ąnger erh├Ąlt und seine eigenen Ergebnisse zur├╝ckgibt.

Die folgende Abbildung zeigt eine einfache Ausf├╝hrungssequenz von drei Testmodulen innerhalb eines Testfalls.

Neben der eigentlichen Ausf├╝hrungs-Methode verf├╝gt die Modul-Schnittstelle zus├Ątzlich ├╝ber eine Methode zum expliziten Beenden eines Moduls. Diese wird in umgekehrter Ausf├╝hrungsreihenfolge aufgerufen und erm├Âglicht die Implementierung von Modulen mit z.B. Hintergrundaufgaben wie beispielsweise das Empfangen von Requests eines "system under test".

Testfall-Definition in XML

Die Definition konkreter Testf├Ąlle soll in einer ersten Ausbaustufe in XML erfolgen. Alternative Repr├Ąsentationen, die ggf. zu einem sp├Ąteren Zeitpunkt ben├Âtigt werden, sollen durch die Architektur ber├╝cksichtigt werden. Dementsprechend werden Mechanismen zum Laden einer Testfall-Definition abstrakt gehalten.

Alternative und multiple Reports

F├╝r unterschiedliche Zielgruppen, sind verschiedene ggf. parallel zu erstellende Reports einer Testfallausf├╝hrung notwendig. Dies sind zun├Ąchst die Reports f├╝r den Auftraggeber mit den eigentlichen Testergebnissen sowie die Reports f├╝r die Softwareentwickler mit detaillierten Hinweisen auf Fehlerursachen. Bei der Erf├╝llung dieser Anforderung war daher zu beachten, einerseits die Schnittstelle f├╝r das Reporting generisch zu halten und anderseits die Konfiguration f├╝r den Report in den Testf├Ąllen logisch von der Ausf├╝hrungskonfiguration zu trennen.

Abstrakte Kriterien f├╝r die Ausf├╝hrungssteuerung

Um ein Set an Testf├Ąllen auszuf├╝hren werden mehrere Komponenten unterschiedlicher Ebene ausgef├╝hrt:

  • Testmodule - Sie kapseln ausf├╝hrbaren Programm-Code in Modulen f├╝r einen Testfall.
  • Testfall - Besteht aus einer Komposition mehrerer Testmodule.
  • Testgruppe - Ist eine Sequenz von Testf├Ąllen
  • Testlauf - Die Ausf├╝hrung aller Testf├Ąlle und -gruppen ist ein Testlauf.

Dabei kann jede Komponente auf den unterschiedlichen Ausf├╝hrungsebenen mit einem von vier Zust├Ąnden terminieren:

  1. Erfolgreich - Test(schritt) entspricht Erwartungen
  2. Nicht Erfolgreich - Test(schritt) entspricht nicht Erwartungen
  3. Abbruch - nicht erheblicher Fehler
  4. Ausnahme - gravierender Fehler

In Abh├Ąngigkeit dieser vier Zust├Ąnde entscheiden Steuerungseinheiten auf jeder Ebene ├╝ber die Ausf├╝hrung nachfolgender Komponenten. Durch die abstrakte Definition der Ausf├╝hrungsbedingungen f├╝r die Schnittstellen der Steuerungseinheiten sind unterschiedliche Implementierungen der Ausf├╝hrungslogik m├Âglich.

So kann beispielsweise eine Implementierung zur Steuerung der Testfall-Ausf├╝hrung vorsehen, dass bei jedem nicht erfolgreichen Testmodul der Testfall abgebrochen wird. Eine andere Umsetzung k├Ânnte zwischen Modulen f├╝r Vor- und Nachbedingungen unterscheiden und damit eine komplexere Steuerung
vorsehen.

Konkreter Testfall - Smart Card Version lesen

Das folgende Beispiel zeigt einen Testfall f├╝r ein System, in dem Smart Cards verwendet werden. Gepr├╝ft wird hierbei, ob eine verf├╝gbare Karte eine erwartete Version hat.

Voraussetzung f├╝r den Testfall ist, dass das System entsprechend konfiguriert und eine gesteckte Smart Card vorhanden ist.

Das "system under test" verf├╝gt ├╝ber eine JSON- und eine SOAP-Schnittstelle. ├ťber die JSON-Schnittstelle wird im Testfall zun├Ąchst die passende Konfiguration geladen. Dann wird ├╝ber die SOAP-Schnittstelle die die Abfrage ├╝ber die verf├╝gbare Karte gestartet.

Anschlie├čend wird das Ergebnis mit einem Extractor aus der SOAP-Response herausgel├Âst. Ein weiterer m├Âglicher Schritt in diesem Beispiel w├Ąre die ├ťberpr├╝fung einer speziellen Kartenversion mit einem daf├╝r geeigneten Validator-Modul.


Dieses Beispiel illustriert die Komposition verschiedener Testmodule in unterschiedlichen Rollen. W├Ąhrend das Laden der Konfiguration im Kontext einer Vorbedingung steht, ist die Abfrage der Kartenversion Bestandteil der Pr├╝fung einer Erwartungshaltung. Dementsprechend unterscheidet die Ausf├╝hrungssteuerung zwischen dem Scheitern eines Moduls in Vorbedingungen und anderen Modulen. So kann z.B. beim Fehlschlag der Vorbedingung der gesamte Testlauf abgebrochen werden.

In der beispielhaften Testfallbeschreibung werden Variablen verwendet, z.B.   ${ip.adress} . Dabei k├Ânnen Variablen statisch definiert werden oder mit Werten aus den Ergebnissen der Testmodule belegt werden.

F├╝r das dynamische Reporting von Testergebnissen k├Ânnen Module ├╝ber Report-Items ihre Ergebnisse an die Report-Schnittstelle geben.

Fazit & Ausblick

Eigene Entwicklung

Die eigene Entwicklung der Test Workbench ist aus unserer Sicht ein lohnenswerter Ansatz gewesen. Der gr├Â├čte Aufwand bei der Entwicklung lag bisher in der Implementierung von Testmodulen f├╝r konkrete Testf├Ąlle. Ablaufsteuerung und Reporting sowie weitere Infrastruktur-Komponenten haben also bezogen auf die Gesamtaufw├Ąnde eine untergeordnete Rolle gespielt. Bei der Verwendung eines bereits vorhandenen Frameworks h├Ątten Aufruf und Evaluierung von Schnittstellen des "system under test" ebenfalls implementiert werden m├╝ssen. Dieser Aufwand entsteht also in jedem Fall.

Komplexit├Ąt von Testfallbeschreibungen vs. spezialisierte Testmodule

Interessant ist aus unserer Sicht auch die Balance zwischen Aufwand bei der Testmodul-Entwicklung und der Komplexit├Ąt konkreter Testfallbeschreibungen. Wird der Testfall durch eine Vielzahl einfacher, generischer Module abgebildet oder lohnt die Entwicklung eines aufwendigeren, spezialisierten Moduls? Die Frage entscheidet sich in der Regel an der Menge ├Ąhnlicher Testf├Ąlle. Kann die Komplexit├Ąt sehr vieler Testf├Ąlle durch die Entwicklung eines komplexen Testmoduls reduziert werden, so entscheiden wir uns f├╝r die Modul-Entwicklung. Auch diesbez├╝glich erm├Âglicht unsere individuelle Entwicklung den gr├Â├čtm├Âglichen Freiheitsgrad bei dieser Abw├Ągung.

Abstrakte Komponenten

Die Abstraktionen bez├╝glich Reporting, Testfall-Definition und Ausf├╝hrungssteuerung haben sich bereits ausgezahlt, da wir f├╝r die drei Bereiche tats├Ąchlich innerhalb kurzer Zeit alternative Implementierungen ben├Âtigten. Durch diese Anpassbarkeit ist die Test Workbench auch f├╝r unsere Kunden interessant, da von der Testfallbeschreibung bis zum Report individuelle Anforderungen umgesetzt werden k├Ânnen, ohne den Kern der Anwendung zu ber├╝hren.

Weitere Entwicklung

Bez├╝glich weiterer Ausbaustufen der Test Workbench werden im Entwicklerteam bereits einige Ideen gehandelt:

  • GUI f├╝r grafische Komposition von Testmodulen
  • GUI zur Verwaltung von Testf├Ąllen
  • Dashboard f├╝r die dynamische Beobachtung eines Testlaufs
  • Analyse-Tools f├╝r die Testergebnisse

Wenn es eine Aufgabe erfordert und die Umsetzung im konkreten Kontext rentabel ist, freuen wir uns auf diese Weiterentwicklungen.