Diese Richtlinie beschreibt, wie Testideen aus Zustandsdiagrammen und anderen Designstrukturen entwickelt werden
können. Solche Designstrukturen bestehen vorrangig aus Knoten, die durch Pfeile miteinander verbunden sind, um einen
Teil der möglichen Steuerungsflüsse eines Programms zu zeigen. Hauptziel dieses Testverfahrens ist es, jeden der
dargestellten Pfeile in einem Test nachzuvollziehen. Ob der von einem Pfeil repräsentierte Steuerungsablauf tatsächlich
funktioniert, können Sie erst wissen, wenn Sie es im Test nachgewiesen haben.
Schauen Sie sich das folgende Zustandsdiagramm an:
Abbildung 1: HVAC-Zustandsdiagramm
Erste Liste mit Testideen:
-
Im Zustand 'Leerlauf' wird das Ereignis 'Zu heiß' empfangen.
-
Im Zustand 'Leerlauf' wird das Ereignis 'Zu kalt' empfangen.
-
Im Zustand 'Kühlen/Starten' wird das Ereignis 'Kompressor aktiv' empfangen.
-
Im Zustand 'Kühlen/Bereit' wird das Ereignis 'Gebläse aktiv' empfangen.
-
Im Zustand 'Kühlen/Aktiv' wird das Ereignis 'OK' empfangen.
-
Im Zustand 'Kühlen/Aktiv' wird das Ereignis 'Störung' empfangen.
-
Im Zustand 'Störung' wird das Ereignis 'Störung behoben' empfangen.
-
Im Zustand 'Heizen' wird das Ereignis 'OK' empfangen.
-
Im Zustand 'Heizen' wird das Ereignis 'Störung' empfangen.
Alle diese Testideen können in nur einem Test umgesetzt werden. Sie könnten aber auch mehrere Tests mit jeweils einigen
der Ideen planen. Wie bei jedem Testdesign sollten Sie auch hier sorgfältig die Einfachheit der Implementierung vieler
einfacher Tests gegen die erhöhte Mängelerkennungsquote bei komplexen Tests abwägen. (Vergleichen Sie hierzu das
Testdesign unter Verwendung der Liste mit Testideen auf der Seite Konzept: Liste mit
Testideen.) Falls Ihre Anwendungsfallszenarien bestimmte Pfade durch das Zustandsdiagramm beschreiben, sollten Sie
bevorzugt diese Pfade testen.
Mit den Tests sollte in jedem Fall überprüft werden, ob alle erforderlichen Aktionen des Zustandsdiagramms tatsächlich
ablaufen. Wird der Alarm beispielsweise beim Eintritt in den Zustand 'Störung' ausgelöst und beim Austritt aus diesem
Zustand gestoppt?
Es sollte auch getestet werden, ob ein Übergang in den nächsten korrekten Zustand erfolgt. Dies kann ein kniffliges
Problem sein, wenn die Zustände von außen nicht erkennbar sind. Ein falscher Zustand kann nur erkannt werden, wenn eine
folge von Ereignissen eingefügt wird, die zu falschen Ausgaben führt. Genauer gesagt müssten Sie eine eine
Ereignisfolge konstruieren, deren von außen sichtbare Resultate für den korrekten Zustand sich von denen
unterscheiden, die dieselbe Folge für jeden denkbaren falschen Zustand haben würde.
Kehren wir zum obigen Beispiel zurück. Wie können Sie wissen, dass das Ereignis 'Störung behoben' den Zustand 'Störung'
richtigerweise beendet und einen Wechsel in den Zustand 'Leerlauf' nach sich zieht? Sie könnten darauf vertrauen, dass
das Stoppen des Alarms ein Zeichen für den Zustandswechsel ist. Es wäre jedoch besser, dies zu überprüfen, indem die
Temperatur so weit abgesenkt wird, dass die Heizung startet, oder so weit erhöht wird, dass die Kühlung anspringt. Wenn
etwas geschieht, haben Sie mehr Sicherheit, dass es zu einem Wechsel in den richtigen Zustand gekommen ist. vollzogen
wurde. Geschieht nichts, befindet sich die Einheit wahrscheinlich noch immer im Zustand 'Störung'.
Schließlich wird das Testdesign dadurch komplizierter, dass festgestellt werden muss, ob der resultierende Zustand der
richtige ist. Oft ist es besser, eine explizite Zustandsmaschine zu verwenden und die Zustände für Tests sichtbar zu
machen.
Weitere Konstrukte in Zustandsdiagrammen
Zustandsdiagramme bestehen nicht nur aus Knoten und Pfeillinien. Nachfolgend sind die Konstrukte von Zustandsdiagrammen
aufgeführt und die Auswirkungen beschrieben, die diese Konstrukte auf die Liste der Testideen haben.
Ereignisaktionen, Eintrittsaktionen und Austrittsaktionen
Diese Konstrukte generieren an sich keine Testideen. In den Tests sollte vielmehr überprüft werden, ob die Aktionen
gemäß Spezifikation ablaufen. Falls die Aktionen eigenständige Programme repräsentieren, müssen diese Programme
getestet werden. Die Testideen für die Programme können mit Testideen zum Zustandsdiagramm kombiniert werden.
Wahrscheinlich lassen sich aber getrennte Tests einfacher verwalten. Entscheiden Sie je nach Aufwand und nach Ihren
Vermutungen bezüglich möglicher Interaktionen zwischen Ereignissen. Falls eine bestimmte, durch einen Pfeil
dargestellte Aktion unmöglich Daten einer durch einen anderen Pfeil dargestellten Aktion austauschen kann, besteht kein
Grund, beide Aktionen in einem Test auszuführen. (Dies wäre notwendig, wenn beide Aktionen Teil desselben Pfades durch
ein Zustandsdiagramm sind.)
Wächterbedingungen
Wächterbedingungen sind Boolesche Ausdrücke. Die Testideen für Wächterbedingungen werden wie im Abschnitt Richtlinie für Arbeitsergebnisse: Testideen für Boolesche Ausdrücke und
Grenzbedingungen beschrieben abgeleitet.
Im obigen Beispiel ist der Wächter für das Beenden des Zustands 'Leerlauf' beim Ereignis 'Zu kalt' [Neustart >= 5
min]. Daraus lassen sich zwei gesonderte Testideen ableiten:
-
Im Zustand 'Leerlauf' wird das Ereignis 'Zu kalt' empfangen, wenn die Zeit bis zu einem Neustart bei fünf Minuten
liegt (Übergang ist erfolgt).
-
Im Zustand 'Leerlauf' wird das Ereignis 'Zu kalt' empfangen, wenn die Zeit bis zu einem Neustart unter fünf Minuten
liegt (Übergang geblockt).
In beiden Fällen sollte getestet werden, ob mit dem Übergang der korrekte Zustand erreicht wird.
Interne Übergänge
Aus internen Übergängen können ähnliche Testideen entwickelt werden wie aus externen Übergängen, nur dass sich bei
einem internen Übergang der Folgezustand nicht vom ursprünglichen Zustand unterscheidet. Hier ist es ratsam, den Test
so einzurichten, dass die Eintritts- und Austrittsaktion des Zustands bei nicht ordnungsgemäßer Auslösung einen
beobachtbaren Effekt hat.
Kompositionszustände
Achten Sie beim Konstruieren von Tests darauf, dass das Eintritts- und Austrittsereignis des zusammengesetzten Zustands
jeweils eine Wirkung hat, die beobachtet werden kann, denn Sie möchten ja bemerken, wenn eines der Ereignisse nicht
eintritt.
Parallele Unterzustände
Das Testen paralleler Unterzustände fällt nicht in den Bereich der Entwicklertest.
Verzögerte Ereignisse
Falls Sie der Meinung sind, dass es einen Unterschied macht, ob ein Ereignis verzögert und in eine Warteschlange
gestellt oder bei Empfangsbereitschaft des Programms generiert wird, sollten Sie diese beiden Fälle testen.
Wenn es für das Ereignis bei Empfangsbereitschaft eine Wächterbedingung gibt, überdenken Sie, welche Änderungen sich
bei den Variablen der Wächterbedingung zwischen dem Generieren und dem Empfang des Ereignisses vollziehen.
Falls ein verzögertes Ereignis in verschiedenen Zuständen empfangen werden kann, sollten Sie erwägen, die Verzögerung
für jeden möglichen Empfangszustand zu testen. Vielleicht wird in der Implementierung ja vorausgesetzt, dass das
Ereignis im "offensichtlichen" Zustand empfangen wird.
Erinnerungszustände
Das folgende Beispiel zeigt einen Erinnerungszustand:
Abbildung 2: Beispiel für einen Erinnerungszustand
Der Übergang in den Erinnerungszustand repräsentiert drei reale Übergänge und damit auch drei Testideen:
-
Das Ereignis 'Sicherung erstellen' führt im Befehlszustand zum Zustand 'Erfassen'.
-
Das Ereignis 'Sicherung erstellen' führt im Befehlszustand zum Zustand 'Kopieren'.
-
Das Ereignis 'Sicherung erstellen' führt im Befehlszustand zum Zustand 'Bereinigen'.
Durchgangszustände
Durchgangszustände haben scheinbar keine Auswirkungen auf das Testdesign, bringen aber weitere Aktionen mit sich, die
überprüft werden müssen.
Bei den bisherigen Erläuterungen lag der Schwerpunkt auf dem Abgleich von Implementierung und Design. Das Design selbst
kann aber auch falsch sein. Wenn Sie das Design unter dem Aspekt von Testideen untersuchen, achten Sie auf die beiden
folgenden Probleme:
Fehlende Ereignisse. Das Zustandsdiagramm zeigt die Reaktion eines Zustandes auf Ereignisse, die nach Meinung
des Entwicklers in diesem Zustand eintreten können. Allerdings kann auch ein Entwickler Ereignisse übersehen. Im
folgenden diesem Zustandsdiagramm (das wir bereits weiter oben betrachtet haben) könnte der Entwickler vergessen haben,
dass auch im Unterzustand 'Bereit' des Zustandes 'Kühlen' eine Störung möglich ist, und nicht nur, wenn da Gebläse
aktiv ist.
Abbildung 3: HVAC-Zustandsdiagramm
Aus diesem Grunde sollten Sie sich für jeden Zustand die Frage stellen, ob Ereignisse, die in anderen Zuständen
eintreten können, auch für diesen Zustand möglich sind. Falls Sie einen Zustand finden, auf den dies zutrifft,
korrigieren Sie Ihr Design entsprechend.
Unvollständige oder fehlende Wächterbedingungen. Wächterbedingungen für einen Übergang können die Anwendung von
Wächterbedingungen auf andere Übergänge nahe legen. Im obigen Zustandsdiagramm wurde beispielsweise Wert darauf gelegt,
die Heizung nicht zu oft einzuschalten. Für das Kühlsystem gibt es jedoch keine solche Einschränkung. Sollte dies so
bleiben?
Aus den Variablen einer Wächterbedingung kann außerdem geschlussfolgert werden, dass andere Wächterbedingungen
möglicherweise zu einfach aufgebaut sind.
Das Testen jedes Pfeils in einer Grafik bedeutet auf keinen Fall, dass die Tests damit vollständig sind. Nehmen wir
beispielsweise an, der Zustand 'Starten' legt für eine Variable den Anfangswert 0 fest, der Zustand 'Festlegen' setzt
die Variable auf 5 und der Zustand 'Dividieren' teilt die Variable in Hundertstel (Variable/100). Wenn es einen Pfad
vom Zustand 'Starten' zum Zustand 'Dividieren' gibt, der nicht über 'Festlegen' führt, liegt eine Ausnahmebedingung vor
(Division durch null). Ein solcher Pfad könnte übersehen werden, wenn für ein Zustandsdiagramm mit vielen Zuständen nur
jeder einzelne Pfeil getestet wird.
Das Testen aller Pfade ist sicher nur bei sehr einfachen Zustandsdiagrammen durchführbar. In der Praxis sind komplexe
Tests, die Anwendungsfallszenarien entsprechen, oft ausreichend.
|