• Keine Ergebnisse gefunden

Einschränkungen zum Klassentest

Im Dokument Das Praxishandbuch für den Test (Seite 180-184)

Unterschiede zwischen Klassentest und Modultest Zweck des Klassentests

6.3 Einschränkungen zum Klassentest

Es mag paradox klingen, aber die Hindernisse beim Klassentest sind im Wesentli-chen identisch mit den Vorzügen der objektorientierten Programmierung. Es sind:

• die Vererbung,

• die Polymorphie,

• das Überladen der Parameter und

• die Wiederverwendung fremder Klassen [CTC+98].

6.3 Einschränkungen zum Klassentest _____________________________________165

Es könnte leicht der Verdacht aufkommen, dass die Väter der objektorientierten Sprachen mit dem Unittest nichts im Sinne hatten. Auf jeden Fall haben sie sich – bis auf Bertrand Meyer, den Vater der objektorientierten Programmiersprache Eiffel ([Mey88]) – wenig Gedanken darüber gemacht. Mit seinen require und ensure Zusicherungen hat Meyer einen testgetriebenen Entwicklungsansatz gewählt, aber Eiffel hat sich leider nicht durchgesetzt. Für den gewöhnlichen Entwickler ist sie zu anspruchsvoll. Ansonsten ist der Klassentest nur unter Berücksichtigung der fol-genden Einschränkungen möglich.

6.3.1 Klassentest und Vererbung

Die Vererbung bestimmt die Reihenfolge des Klassentests. Da abgeleitete Klassen – ähnlich wie verschachtelte Prozeduren – die Daten und Operationen ihrer Ober-klassen mit benutzen, ist es nicht möglich, abgeleitete Klassen für sich allein zu testen. Sie müssen zusammen mit ihren Oberklassen getestet werden. Wenn diese Klassen auch abgeleitet sind, werden ihre Oberklassen mitgetestet (Abbildung 6.3).

Es ist wie Spaghetti essen: wer einen Strang herausholen will, bekommt die ganze Schüssel mit. Daraus ergibt sich eine strenge Reihenfolge, nach der getestet werden muss. Am Anfang sind die Klassen an der Spitze der Klassenhierarchie zu testen, d.h. jene, die keine Ahnen mehr haben. Sie sind die Wurzel des Klassenbaums. Von dort aus wird die jeweils nächste Schicht von abgeleiteten Klassen bis hin zu den Blättern am anderen Ende des Baums getestet.

Konto.Girokonto.Inlandskonto

Test Test

Konto

Spar-konto

Giro-konto

Auslands-konto

Inlands-konto Abbildung 6.3 Klassentest mit Vererbung

Ursprünglich haben Verfechter der objektorientierten Programmierung behauptet, man brauche in den abgeleiteten Klassen nur die neu hinzugekommenen Methoden zu testen. Dies hat sich jedoch als Fehlannahme erwiesen. Da die Umgebungsbe-dingungen sich ändern, ist es schon erforderlich, auch die geerbten Methoden mit

zu testen. Sie werden als Bestandteile der abgeleiteten Klasse behandelt. Die dafür erforderliche Technik heißt „class flattening“ [Bin99].

Dies führt dazu, dass der Testgegenstand eines Klassentests sehr groß werden kann.

Er umfasst nicht nur die Zielklasse, sondern alle darüber liegenden Ahnenklassen.

Dies spricht gegen die Mehrfachvererbung und gegen tiefe Vererbungshierarchien.

Beide erschweren den Klassentest.

6.3.2 Klassentest und Polymorphie

Die dynamische Bindung erschwert die Kontrolle des Klassentests, denn wenn es aus dem Text der Klasse nicht ersichtlich ist, welche Variante einer Operation aus-geführt wird, ist es auch nicht determinierbar, welches Ergebnis zurückkommt. Z.B.

wird eine fremde Methode namens „Validation“ aufgerufen. Diese Methode gibt es in Dutzenden Klassen. Welche Ausprägung davon wirklich aufgerufen wird, wird erst zur Laufzeit entschieden (Abbildung 6.4). Thuy meint, man müsse beim Klas-sentest alle möglichen Ausprägungen testen:

“... class coverage is complete only when all the redefinitions of the called method have been exercised.” [Thu93]

Validate (Betrag)

Validate (Betrag)

Validate (Betrag) ...

Validate (Betrag) ...

Zielobjekte DEM

EUR

USD

DEM.Validate

DOLLAR.Validate EURO.Validate

Alle potentiellen Zielfunktionen sind zu testen

Abbildung 6.4 Klassentest mit Polymorphie

Dies würde bedeuten, dass der Tester einen Teststellvertreter (stub) für jede Aus-prägung der Zielmethode schreibt, z.B. Betrag.validation(),

Na-me.validation(), Datum.validation(), usw. Um nicht ins Uferlose zu geraten, muss der Tester hier eine Entscheidung treffen, welche Validations-Operationen für

6.3 Einschränkungen zum Klassentest _____________________________________167

die Klasse unter Test relevant sind, und ihre Ergebnisse simulieren. Dies bedeutet allerdings eine Einschränkung in der Testüberdeckung.

Andererseits, falls die polymorphe Methode zur Klasse unter Test gehört, muss der Tester im Testtreiber alle möglichen Aufrufe mit allen möglichen Parametervariati-onen einbauen. D.h., wenn die Klasse Datum getestet wird, muss die dazugehörige Methode „Validation“ für alle möglichen Datumsarten wie z.B. Julianisch, Gregori-anisch usw. getestet werden. Dadurch führt die Polymorphie zu einer Explosion von Testfällen.

6.3.3 Klassentest und Überladen von Parametern

Die dynamische Veränderung der Parameter ist eine beliebte Technik der Objekt-orientierung zur Erzielung unterschiedlicher Ergebnisse mit ein- und demselben Operationsaufruf im Code. Dies erhöht zwar die Flexibilität der Anwendung, erhöht aber gleichzeitig den Testaufwand, denn es müssen alle potenziellen Parameter-kombinationen getestet werden bzw. mindestens jene, die am wahrscheinlichsten vorkommen. Diese Technik erschwert auch die Generierung eines Testtreibers, weil der generierte Testtreiber nur die eine Standard-Parameterliste kennt. Die verschie-denen Variationen müssen manuell im Testtreiber angepasst werden. Auch dies erhöht den Aufwand für den Klassentest [SmRo92].

6.3.4 Klassentest und Wiederverwendung

Wenn der Tester wirklich davon ausgehen könnte, dass fremde Klassen in jedem beliebigen Zusammenhang wiederverwendet werden könnten, wäre es kein Prob-lem, sie in den Klassentest einzubinden. Leider ist dies jedoch selten der Fall.

Fremde Klassen sind ebenso eine Fehlerquelle wie die eigenen. Das hat zur Folge, dass sie im Klassentest entweder durch Stubs zu simulieren oder direkt mit zu tes-ten sind. Dieses „Mittestes-ten“ bedeutet, ihre Rückgabewerte genau zu kontrollieren, z.B. durch Zusicherungen, um auszuschließen, dass sie die eigenen Klassen nicht mit ungültigen Ergebnissen korrumpieren [Ros95].

Zusammenfassend ist festzustellen, dass der Klassentest um einiges komplizierter und aufwändiger ist als der konventionelle Modultest. Er setzt anspruchsvollere Testwerkzeuge und eine weitaus höhere Ausbildung der Tester voraus. Insofern hat Beizer Recht, wenn er von einer Kostensteigerung von 300% spricht[Bei99]. Dies kann durchaus zutreffen.

Im Dokument Das Praxishandbuch für den Test (Seite 180-184)