Agile Modellierung mit
UML
Loading

8.1 Dummies

Ein Dummy ist ein Objekt, das einen Teil der Umgebung des Testlings simuliert und dem Testling damit eine Umgebung zur Verfügung stellt, in der sein Verhalten geprüft werden kann. Die Verwendung von Dummies hat sich durch die objektorientierte Programmierung wesentlich vereinfacht, weil sich durch Vererbung und dynamisches Redefinieren von Methoden und durch die Implementierung von Interfaces relativ leicht Dummy-Objekte ins System einbringen lassen, ohne den Produktionscode davon durch syntaktische Beziehungen (beispielsweise import) abhängig zu machen. Abbildung 8.1 zeigt, wie typischerweise Dummy-Klassen definiert werden. Diese Klassen erhalten per Konvention den Suffix „Dummy“, lassen sich aber auch durch einen geeigneten Stereotyp Dummy kennzeichnen und stehen nur im Testsystem zur Verfügung.


Abbildung 8.1: Dummy-Klassen redefinieren Methoden

Damit können beispielsweise Testfälle für die Klasse Auction aufgebaut werden. Abbildung 8.2 zeigt einen Ausschnitt eines Objektdiagramms, das für den Aufbau solcher Testfälle verwendet wird.


Abbildung 8.2: Testsituation für ein Auction-Objekt

In den Dummy-Klassen können Methoden geeignet überschrieben werden, die während des Tests verwendet werden. Eine einfache Dummy-Methode gibt ein vorgegebenes, konstantes Ergebnis zurück oder liest Ergebnisse der Reihe nach aus einer Liste. Beispielsweise wurde im Auktionsprojekt das auf einen Test spezialisierte Dummy aus Abbildung 8.3 verwendet, um Zeitabfragen zu simulieren.

       Java/P   
   
 class TimingPolicyDummy implements TimingPolicy {
  Time[] timelist = new Time[] {
        new Time("14:42:22", "Feb 21 2000"),
        new Time("14:42:23", "Feb 21 2000"),
        new Time("14:44:18", "Feb 21 2000"),
        new Time("14:59:59", "Feb 21 2000") };
  int count = 0;
 
  public Time newCurrentClosingTime(Auction a, Bid b) {
    ocl count < timelist.length;
    return timelist[count++];
}}
Abbildung 8.3: Dummy mit Ergebnissen für vier Aufrufe

Für die Tests einfacher Klassen mit wenig Funktionalität sind meist keine Dummies notwendig. Für andere Klassen können abhängig vom Testzweck mehrere verschiedene Dummies notwendig sein. Entsprechend werden mehrere Klassen oder eine parametrisierte Dummy-Klasse realisiert. Zum Beispiel kann TimingPolicyDummy einen Konstruktor mit der Liste der auszugebenden Time-Objekte als Parameter anbieten oder mehrere Listen besitzen, von denen eine ausgewählt wird.

8.1.1 Dummies für Schichten der Architektur

Abhängig vom Testziel können statt einzelnen Objekten auch Gruppen von Objekten getestet werden. Zum Beispiel lässt sich die Funktionalität des Servers dadurch testen, dass sowohl die Policy- als auch die Personen-Objekte jeweils aus dem Produktionssystem sind und nur deren Umgebung wie Persistenzmechanismen, Protokollierung und Internet-Anschluss durch Dummies ersetzt werden. Generell lassen sich für Tests verschiedene Umgebungen gruppieren. So schlägt [Bin99] Tests für einzelne Schichten einer Architektur nach dem in Abbildung 8.4 gegebenen Muster vor. Dabei wird jeweils eine Schicht getestet und die darunterliegende Schicht durch Dummies ersetzt (a), (b). Bei weitergehenden Integrationstests (c) können auch Schichten gekoppelt werden. Da eine Schicht selbst aus einer Gruppe von Objekten besteht, kann diese umgekehrt auch zerlegt werden und durch Klassen- und Methodentests, wie bereits gezeigt, einzelne Objekte getestet werden.

Abbildung 8.4: Testumgebungen in der Schichtenarchitektur

Ruft die zu testende Methode andere Methoden desselben Objekts auf, so kann es sinnvoll sein, von der Klasse mit dem Testling selbst eine Unterklasse zu bilden und darin die aufgerufenen Methoden durch Dummy-Methoden zu ersetzen. Testling und Dummy sind dann im gleichen Objekt.

8.1.2 Dummies mit Gedächtnis

Eine Verfeinerung der Testumgebung kann dadurch vorgenommen werden, dass diese mitprotokolliert, in welcher Form sie vom Testling genutzt wird und gegebenenfalls dieses Gedächtnis nutzt, um die Return-Ergebnisse daraus zu berechnen. Im Umfeld des Extreme Programming-Ansatzes [MFC01] werden solche Dummies auch Mock-Objekte und in Telekommunikations-nahen Ansätzen Stubs genannt. Ein einfaches Beispiel ist bereits in Abbildung 8.3 gegeben. Mit dem Dummy-Objekt kann nach Ende des Tests geprüft werden, wie oft die Methode newCurrentClosingTime aufgerufen wurde, indem der Zählerstand ausgelesen wird.

Ein weiteres Beispiel für einen solchen Dummy mit nachträglicher Abfragefunktion bietet ein Protokollobjekt, das zur Protokollierung von wesentlichen Ereignissen im Auktionssystem dient. Dazu gehört zum Beispiel auch die Mitteilung über die Abgabe eines neuen Gebots. Deshalb wird neben den eigentlichen Testdaten ein Dummy-Objekt der Klasse ProtocolDummy realisiert. Abbildung 8.5 zeigt das Klassendiagramm für eine vereinfachte Form der Protokollierung. Mit der Klasse ProtocolDummy können nun Tests um das Protokoll erweitert werden. Dabei können im Testdatensatz das Objektdiagramm ProtBefore und im Sollergebnis zum Beispiel ProtAfter aus Abbildung 8.6 zum Einsatz kommen.2

       Java/P   
   
 class ProtocolDummy {
  writeToLog(String text) {
    logCount++;
    logLastLine = text;
  }
}
Abbildung 8.5: Protokoll-Dummy erlaubt das Abfangen von Seiteneffekten

Der hier dargestellte Dummy speichert nur die letzte Zeile sowie die Gesamtzahl aufgetretener Meldungen. Manchmal ist auch die Speicherung aller Meldungen in einer Liste oder die selektive Speicherung nach bestimmten Mustern im String sinnvoll.


Abbildung 8.6: Objekt des Protokoll-Dummy beschreibt das Sollergebnis

8.1.3 Sequenzdiagramm statt Gedächtnis

Im ProtocolDummy ist ein Gedächtnis notwendig, damit auf Basis der gespeicherten Daten Rückschlüsse auf die während des Testablaufs durchgeführten Interaktionen vorgenommen werden können. Da Sequenzdiagramme geeignet sind, Interaktionen zu protokollieren, können sie als Ersatz für speichernde Dummies eingesetzt werden. Abbildung 8.7 beschreibt den Protokoll-Aspekt des Testablaufs aus Abbildung 7.12, indem es angibt, wie oft und mit welchen Argumenten die Methode writeToLog aufgerufen wird.


Abbildung 8.7: Sequenzdiagramm prüft Protokollverhalten

Die Methode writeToLog muss im Dummy der Klasse Protocol kein Gedächtnis besitzen. Stattdessen reicht es, zum Beispiel durch einen leeren Rumpf sicherzustellen, dass keine Seiteneffekte auftreten. Dafür wird die automatisch generierte Klasse ProtocolSimpleDummy eingesetzt.

Wegen der doch öfter auftretenden Änderungen bei der Ausgabe von Texten ist es oft besser, statt einer vollständigen Angabe des Protokolltexts nur bestimmte Eigenschaften zu fordern. So kann der Methodenaufruf mit writeToLog(s) modelliert werden und der String s auf das Enthaltensein von Angaben geprüft werden: s.indexOf("552.000,00 $US")>=0.

Das Beispiel in Abbildung 8.7 enthält neben dem Treiberobjekt auch einen Dummy. Dies demonstriert, dass Dummies in Sequenzdiagrammen wie normale Objekte eingesetzt werden können, so dass die gesamte Interaktion im Testablauf modelliert werden kann. Allerdings bedeutet dies, dass auch Dummies vom Generator zu instrumentieren sind, um eine Beobachtung zu ermöglichen.

8.1.4 Abfangen von Seiteneffekten

Das im vorherigen Abschnitt angewandte Verfahren demonstriert, wie ein Testling in eine Testumgebung von „oben“ durch den Testtreiber und von „unten“ durch Dummies in eine Testumgebung eingebettet werden kann und damit auf allen Seiten die für die Prüfung des Testerfolgs relevanten Daten und Interaktionen gesichert werden können. Insbesondere können auf diese Weise alle Effekte des Testlings, die die Systemumgebung verlassen, verhindert werden. Die Verhinderung von Seiteneffekten ist eine wesentliche Voraussetzung für schnelle und effiziente Tests.

Allerdings muss auch die Protokoll-Klasse selbst getestet werden. Generell ist für Tests der letzten Schicht vor einem Dateisystem, einer Datenbank oder einer Kommunikationsschicht Aufwand zu betreiben, um eine definierte Ausgangssituation der Umgebung sicherzustellen, nach Ende des Tests auf die Testergebnisse zugreifen zu können und aufzuräumen. Beispielsweise müssen Protokoll-Dateien oder die Datenbank entsprechend eingerichtet sein. [LF02] enthält dazu detaillierte Beschreibungen. Abschnitt 8.5 dieses Buchs behandelt nur die Simulation verteilter Kommunikation ohne die Verteilung tatsächlich durchzuführen.


Bernhard Rumpe. Agile Modellierung mit UML. Springer 2012