|
seiner Implementierung als Computerprogramm überhaupt
durchgeführt werden. In der Regel können auf Grund der
Komplexität nicht alle möglichen Variationen der Eingabedaten
für Tests verwendet werden. Hat z.B. eine Programmfunktion zwei
Eingangsvariable deren jeweiliger Wertebereich 2^64 ist, so
wären theoretisch 2^128 unterschiedliche
Eingabedaten-Möglichkeiten zu testen. Selbst wenn nur eine
Picosekunde für jeden einzelnen Test veranschlagt wäre, so
käme man auf knapp 4 * 10^21 Tage Rechenzeit. Damit ist klar,
daß nicht alle Fehler durch Tests aufgedeckt werden können.
Deshalb ist es nicht verwunderlich, wenn Tests des
Softwareentwicklers keine Fehler mehr zu Tage bringen, Tests des
Softwareanwenders aber schon. Die sinnvolle Auswahl der
Testfälle ist entscheidend. Dazu gibt es
unterschiedliche Sichtweisen, was getestet werden soll. Hier zwei
Beispiele:
Black-Box Test
Der Black-Box-Test ist ein sog. funktionaler Test. Er
betrachtet das Softwaresystem (Algorithmus) als schwarzen Kasten,
in den man nicht hineinschauen kann. Der Anwender einer Software
ist ein klassischer Black-Box Tester. Er ist nur an den
versprochenen Funktionen interessiert, wie die Software intern
funktioniert ist ihm egal. Also werden im Black-Box-Test alle
vereinbarten Funktionen durch systematische Benutzung mit
sinnvollen Testfällen aus Anwendungssicht benutzt. Dies ist in
der entsprechenden Spezifikation im Vorhinein niedergelegt. Der
Black-Box-Test ist der klassische Abnahmetest. Der Kunde, der
Software kauft, testet sie nach der Lieferung, oftmals im Beisein
des Entwicklers, und wenn sie aus seiner Sicht funktioniert muß
er sie bezahlen. Auch in der Entwickung selbst wird dieses
Verfahren häufig eingesetzt. Jeder Algorithmus und jede
Programmfunktion ist i.d.R. schriftlich spezifiziert, d.h. es ist
festgelegt was sie unter welchen Umständen wie können muß.
Somit testet der Entwickler sein Programm gegen die Spezifikation
mit daraus abgeleiteten Testfällen.
Problematisch beim Black-Box-Testverfahren ist die sogenannte
Testüberdeckung.
Die Internas des Programms werden nicht berücksichtigt. So kann
es vorkommen, daß gewisse Programmteile, wie Schleifen oder
Abfragen, bei solchen Tests nie oder immer mit 'harmlosen' Daten
durchlaufen werden. Sinnvolle Testfälle, die sich nicht aus der
Verwendung, sondern einzig aus dem Aufbau und der Formulierung
des Programms ergeben, werden beim Black-Box-Test nicht
systematisch durchgeführt. Die Konsequenz: unendeckte Fehler.
Um dies zu vermeiden gibt es das Prinzip des wesentlich
aufwendigeren White-Box-Tests.
White-Box-Test
Ausgehend vom Programmquelltext werden im White-Box-Test der
Kontrollfluß des Programms untersucht und Testfälle daraus
abgeleitet. Der Kontrollfluß ist der Weg durch das Programm den
dessen Ausführung durch den Rechner nimmt. Alle möglichen Wege
mit allen möglichen Datenkombinationen zu testen ist i.d.R. zu
aufwendig.
Eine Variante des White-Box-Tests sieht vor, daß die
Testfälle so generiert werden, daß zumindest alle
Programmanweisungen mindestens einmal durchlaufen werden. Dieser
wird Anweisungsüberdeckungtest oder auch Co
-Test genannt.
Durch Verzweigungen im Programm kann eine Anweisung auf
mehreren Wegen erreicht werden. Der Anweisungsüberdeckungstest
nimmt hier keine Rücksicht. Hauptsache jede Anweisung ist einmal
durchlaufen:
(entnommen aus "Lehrbuch der Software-Technik" von Helmut Balzert)
Im Bild steht jeder Kreis für eine Anweisung des in der
Bildmitte aufgeschriebenen C++-Programms und jeder Pfeil für
einen möglichen Pfad den das Programm während seiner
Ausführung nehmen kann. Diese Art der Graphik nennt man
Kontrollflußgraph. Wie links im Bild zu erkennen ist wird bei
einem Anweisungsüberdeckungstest von n-Start bin n-Final jede
Anweisung n1 - n6 durchlaufen aber nicht unbedingt jeder Pfeil.
Beim sog. Zweigüberdeckungtest, auch C1-Test
genannt, werden Testfälle so konstruiert, daß alle Zweige
durchlaufen werden. Dieser ist einsichtig aufwendiger als der
Anweisungsüberdeckungstest. Aber selbst dieser reicht nicht aus
um alle Fälle abzudecken.
Schleifen (while..) und datenabhängige Verzweigungen
(if..else..) führen zu unterschiedlichen Wegen durch das
Programm, diese werden Pfade genannt. Die
Kombination der beschrittenen Zweige, im Bild von oben nach unten
betrachtet, hat unterschiedliche Auswirkungen und kann somit
Fehlerquelle sein. Dieses berücksichtigen die sehr aufwendigen
Pfadüberdeckungtests.
Selbst hier ist noch nicht alles getan. Die
datenabhängigen Verzweigungen haben meist komplexe
Entscheidungsbedingungen:
if (A && B || C ) {...} else { ...}
Das Ergebnis True/False der Bedingung A && B || C
hängt von den Ergebnissen der Bewertung der Teilausdrücke A, B, C ab.
Eigentlich müßten für alle möglichen Wertekombinationen diese
Teilausdrücke die Verzweigung getestet werden. Im
Pfadüberdeckungstest wird hierauf nicht Rücksicht genommen.
Erst der sog. Bedingungsüberdeckungstest
kümmert sich darum.
Betrachtet man nun noch die möglichen Daten die ein Programm
erzeugt und die es eingespeist bekommt, so finden noch die sogenannten
datenflußorientierten Testverfahren
Anwendung. Statt nur den Kontrollfluß zu
betrachten wird hier der Datenfluß mit den möglichen Werten und
Wertebereichen der einzelnen Variablen im Programm untersucht.
In der Praxis wird man sich für einen sinnvollen
realisierbaren Mix aus den vorgestellten White-Box-Testverfahren
und dem Black-Box-Testverfahren entscheiden.
Bei der Auswahl der Testdaten kann man sich von folgenden Gesichtspunkten leiten
lassen:
- wähle die Testdaten so, daß das Programm für alle Aufgaben,
die in der Spezifikation gefordert werden, getestet wird,
- man wähle die Testdaten möglichst so, daß jeder Zweig des
Programms mindestens einmal durchlaufen wird,
- man wähle spezielle Testdaten derart, daß alle Sonderfälle
des Programms erfaßt werden,
- man wähle zufällige Testdaten, auch wenn sie nicht sinnvoll
erscheinen, um Testlücken aufgrund scheinbarer Selbstverständlichkeiten
zu vermeiden.
|
|
|