Testende Verfahren

Kontrollflussorientierte Strukturtestverfahren

Anweisungsüberdeckungstest (C0-Test)

  • Verlangt die Ausführung aller Anweisungen (Knoten)
    • 100% Überdeckung bedeutet jede Anweisung wurde überprüft
  • Testpfad enthält alle Knoten aber nicht alle Kanten
  • Überdeckungsgrad = Zahl der ausgeführten Anweisungen / Gesamtzahl aller Anweisungen

Bemerkungen:

  • Wesentliche Aspekte eines Programms werden nicht geprüft!
  • Notwendige, aber nicht hinreichende Testbedingung
  • Toter Code kann gefunden werden
  • Nur in Kombination mit anderen Verfahren sinnvoll (18 % Fehleridentifizierung)

Zweigüberdeckungstest (C1-Test)

  • auch Entscheidungsüberdeckungstest
  • Verlangt die Ausführung aller Zweige (Kanten)
  • Korrektheit des Kontrollflusses an Verzweigungen wird kontrolliert

Bemerkungen:

  • Nicht ausführbare Zweige können gefunden werden
  • Fehlende Zweige können nicht entdeckt werden
  • Höhere Fehleridentifizierungsquote als Anweisungsüberdeckungstest, Leistungsfähigkeit schwankt zwischen 25 und 75 %
  • Gilt als das minimale Testkriterium
  • Unzureichender Schleifentest → Pfadüberdeckungstest notwendig
  • Keine Berücksichtigung von Abhängigkeiten zwischen Zweigen → Pfadüberdeckungstest notwendig
  • Nicht für Test komplexer Bedingungen → Bedingungsüberdeckungstest

Pfadüberdeckungstests

Ausführung aller unterschiedlichen Pfade im Programm

Allgemeiner Pfadüberdeckungstest

Problem:

  • Schleifen mit unbekannter Zahl an Wiederholungen
  • Bei aufeinander folgenden Schleifen steigt die Zahl der Testfälle multiplikativ
  • Schleife mit N Durchläufen und einer inneren Verzweigung fordert 2N Testfälle

Bemerkungen:

  • Einige (konstruierbare) Pfade können sich gegenseitig ausschließen
  • Sehr mächtiges kontrollflussorientiertes Testverfahren
  • Praktische Bedeutung nur für Programmteile ohne Schleifen

Boundary Interior-Test

Eingeschränkter Pfadüberdeckungstest, im Durchlauf wird nur zwischen keinmal, einmal und mehrmals unterschieden → dadurch praktisch anwendbar

Unterscheidung in 2 Gruppen:

  • Grenztest-Gruppe (bondary tests): Pfade, wobei die Schleife nur einfach durchlaufen wird
  • Gruppe zum Test der Reinitialisierung (interior tests): Pfade, die die Schleife mindestens einmal wiederholen

Strukturierte Pfadtest: Verallgemeinerung des Boundary Interior Test

Bedingungsüberdeckungstest

  • Zur Analyse der Testbedingungen in Schleifen und Verzweigungen aus struktureller Perspektive
  • Ansatz:
    • Bedingung ist logische Verknüpfung atomarer boolescher Funktionen
    • Testfälle sollen verschiedene Kombinationen abdecken

Varianten:

  • Einfache Bedingungsüberdeckung
    • Weder Zweig- noch Anweisungsüberdeckung → sehr schwach
  • Mehrfach-Bedingungsüberdeckung
    • Zweigüberdeckung enthalten → sehr aufwendig
  • Minimale Mehrfach-Bedingungsüberdeckung
    • Unter Beachtung der hierarchischen Struktur
    • Überdeckung nicht nur der Blätter, sondern aller Teilbäume
    • → sinnvolle Weiterentwicklung des Zweigtests

Auswahl geeigneter kontrollflussorientierter Testverfahren

  • Programm im Quelltext?
    ⇒ Falls nicht, kein Strukturtest möglich
  • Besteht Programm nur aus Anweisungen?
    ⇒ Anweisungsüberdeckung sinnvoll
  • Besteht Programm nur aus Anweisungen und Verzweigungen mit atomaren Testbedingungen?
    ⇒ Zweigüberdeckung
  • Besteht Programm aus Anweisungen, Verzweigungen und Schleifen mit atomaren Testbedingungen?
    ⇒ Pfadüberdeckung
    je nach Komplexität der Schleifensemantik doppelte oder mehrfache Schleifenüberdeckung
  • Besteht Programm aus komplexen Testbedingungen?
    ⇒ Kopplung geeigneter Verfahren mit Bedingungsüberdeckung

Datenflussorientierte Strukturtests

Dynamisches Strukturtestverfahren zum Test der Datenbenutzungen

Aufstellung eines Datenflussdiagramms mit

  • Sichtbarkeit und Lebensdauer von Bezeichnern
  • Variablenidentitäten
  • Lesenden und schreibenden Zugriffen auf die Variablen
  • Unterscheidung der lesenden Zugriffe in Anweisungen und Bedingungen

Besondere Eignung für Datenobjekte bzw. -klassen

Kennzeichnung durch Pfeil, ob Lese- oder Schreibzugriff ( a ← = ← a + 1)

Klassifikation:

  • Zuweisung (def): Änderung des Variablenwertes
  • Berechnung v. anderen Werten (computational-use, c-use)
  • Berechnung v. Wahrheitswerten (predicate-use, p-use)

Testverfahren

  • all-defs-Kriterium:

Testfälle sind so zu wählen, dass jeder Zuweisung auch eine Wertbenutzung folgt (exemplarische Überprüfung der Variablensemantik)

  • Zu jeder Variablen gibt es einen Testfall, wo die Variable mindestens einmal geschrieben und gelesen wird → sonst Programm-Fehler
  • all-p-uses-Kriterium:

Testfälle so wählen, dass jede Kombination einer Wertzuweisung mit einer prädikativen Nutzung des Wertes überdeckt wird (Prüfung der Auswirkung einer Zuweisung auf alle relevanten Bedingungsknoten); beinhaltet Zweigüberdeckung

  • all-c-uses/some-p-uses-Kriterium:

Testfälle so wählen, dass jede Kombination einer Zuweisung mit jeder berechnenden Nutzung überdeckt wird (Überprüfung aller kausal abhängigen Ausdrücke und exemplarischer Test von bedingungsrelevanten Variablen)

  • bei keinem berechnendem Zugriff mind. eine Nutzung als Prädikat
  • all-p-uses/some-c-uses:

umgekehrt wie all c-uses/some p-uses

  • all uses:

Testfälle werden so gewählt, dass jede Kombination der Zuweisung mit jeder Nutzung überdeckt wird (komplettester, aber aufwändigster Test)

Funktionale Testverfahren

Idee: Ableitung der Testfälle aus Programmspezifikationen, Black-Box-Test (ohne Quelltexte möglich)

Ziel: Test der Programmsemantik auf Erfüllung der Spezifikation

Bildung von Äquivalenzklassen für Testdaten:

  • Exemplarischer Vertreter pro Klasse
  • Klasseneinteilung für „typisches Programmverhalten“
  • Korrektheit eines Vertreters einer Klasse lässt Korrektheit der ganzen Klasse erwarten (kein Beweis dafür!)
  • Bewertung:
    • Zur Herleitung repräsentativer Testfälle
    • Nur Betrachtung einzelner Werte, nicht von Wechselwirkungen oder Abhängigkeiten
  • Bildung von Klassen: Falls Eingabebereich =
    • Ein zusammenhängender Wertebereich: 3 Klassen, eine gültige, 2 ungültige (rechts und links vom Wertebereich)
    • Eine Menge von Werten, die alle unterschiedlich behandelt werden: für jeden gültigen Wert eine Klasse, eine Klasse für alle ungültigen Werte
    • Eine Bedingung, die erfüllt werden muss: eine Klasse für Werte, die die Bedingung erfüllen und deren Komplement
  • Grenzwertanalyse: Erweiterung und Verbesserung der funktionalen Aquivalenzklassenbildung durch Test mit Werten, die am Rand einer Klasse liegen → Erfahrung sagt, dass mit Grenzwerten Fehler besonders effektiv entdeckt werden

Test von Zustandsautomaten:

  • Idee: Software ist als Menge von Zuständen und Übergängen modelliert → min. Teststrategie: jeder Übergang ist min. einmal abzudecken
  • Überdeckung aller Übergänge garantiert keinen vollständigen Test → vgl. Zweigüberdeckung

Bewertung:

  • Gut für Klassen, falls Objektlebenszyklus bekannt
  • Gut geeignet, falls Spezifikation als Zustandsautomat vorliegt

Test von GUI-Komponenten und anderen ereignisbasierten Teilen:

  • Ereigniskonzept als Kommunikationsebene, modelliert Nebenläufigkeit
  • Auslösung durch man. Nutzerinteraktion → Automatisierung problematisch, mgl: manuelles Feuern von Events im Testcode
  • Testfall simuliert speziellen Anwendungsfall in speziellem Programmzustand mit eingeschränkten funktionellen Möglichkeiten
  • → Zustandsdiagramm → Generierung von Testfällen nach dieser Strukturierung (oft hierarchisch)
  • Planung von GUI-Tests:
  1. Ermittlung der primitiven Operationen (1-zu-1 zu direkten Mausaktionen)
  2. Unter diesen die Expansionsoperatoren (z. B. Pull-down) ermitteln
  3. Konstruktion eines Zwischenoperators für jeden Interaktionsop. (z. B. für Edit: Cut, Paste → Edit + Cut und Edit + Paste)
  4. Unter diesen abstrakte Operatoren ermitteln, die GUI-Operation monopolisieren (Modaldialoge)
  5. Identifikation gemeinsamer Teilaktionen, da hierfür nur einmal Testfälle erforderlich sind
  6. Planung der Testfälle, zuerst höherwertige, abstrakte Op., danach schrittweise Verfeinerung

Testen von Klassen

Klasse = kleinste sinnvolle Testeinheit im OOP-Bereich
Besonderheiten:

  • Wiederverwendbarkeitskonzept: Allgemeinheit von K führt zu vielen Testfällen
  • Vererbung von Attributen und Methoden: Eliminierung von Redundanz vs. zusätzlichen Abhängigkeiten
  • Polymorphismus, dynamisches Binden: Test jeder möglichen Bindung erforderlich
  • Unterscheidung: normale K, abstrakte K, parametrisierte K

Testen normaler Klassen:

  • Erzeugung einer Instanz der zu testenden Klasse
  • Überprüfung jeder Op. für sich; zuerst die, die Zustand nicht ändern
  • Test jeder Folge abhängiger Operationen
    • Simulation von allen Objektausprägungen (bzw. Äquivalenzklassen) durch Testfälle
    • Bei Objektlebenszyklus Zustands- bzw. Zustandsüberdeckungstests
  • Testüberdeckung überprüfen (klassisch, w.o.), ggf. zusätzliche Testfälle hinzufügen

Testen abstrakter Klassen:

  • Umwandlung in konkrete Klasse, Umwandlung abstrakter Operationen durch leere oder spezifikationsgemäße Implementierung

Testen parametrisierter Klassen:

  • Einfache konkrete Klasse erzeugen, Testdaten so wählen, dass Test möglichst einfach wird

Testen von Unterklassen (erbenden Klassen):

  • Neuer Kontext erfordert erneuten Test aller geerbten Operationen
  • Überschriebene Operationen brauchen neue strukturelle Testfälle
  • Überschriebene Operationen müssen alten Testfällen genügen und durch neue ergänzt werden (Test der neuen Semantik!)

Kontext

Weiterführende Beiträge


Navigation

Alphabetischer Index
Akronyme