Paarweises Testen

Wie paarweises Testen Parameterkombinationen reduziert und Aufwand spart, ohne auf sinnvolle Abdeckung zu verzichten.

Aktualisiert:

Inhalt

Viele Parameter und Werte machen vollständige Kombinationstests teuer. Paarweises Testen reduziert die Anzahl der Tests und deckt dabei jedes Paar von Parameterwerten ab. Es bietet häufig einen Ausgleich zwischen Testaufwand und Wahrscheinlichkeit, Fehler zu finden.

Warum paarweises Testen hilft

Viele Fehler entstehen durch Wechselwirkungen zweier Faktoren statt durch seltene Kombinationen von fünf oder sechs. Die Abdeckung aller Paare kann deshalb einen erheblichen Teil der Probleme mit deutlich weniger Tests aufdecken.

Wo es eingesetzt werden kann

  • →Formulare mit mehreren unabhängigen Feldern und Werten.
  • →Kombinationen von Geräten, Browsern, Rollen, Tarifen, Ländern und Sprachen.
  • →APIs mit vielen Parametern und Aufrufmodi.
  • →Kompatibilitätsmatrizen, bei denen vollständiges Testen zu teuer ist.

Was zu beachten ist

  • →Paarweises Testen ersetzt weder kritische Geschäftsrisikotests noch bekannte gefährliche Kombinationen.
  • →Abhängige Parameter dürfen nicht unbesehen wie unabhängige kombiniert werden.
  • →Logisch unmögliche Kombinationen vorher ausschließen.
  • →Kritische Szenarien zusätzlich zum erzeugten paarweisen Testsatz aufnehmen.

Praktische Hinweise

Paarweises Testen zur Optimierung der Abdeckung verwenden, nicht zur Rechtfertigung der kleinstmöglichen Suite. Hochrisikofälle manuell bestimmen, paarweise Kombinationen für breitere Abdeckung ergänzen und diese mit Negativ- und Grenzszenarien verstärken.

🧩

Paarweises Testen hilft, wenn Parameterkombinationen das eigentliche Problem sind. Es ist keine universelle Lösung für komplexe Abläufe, Zustände oder Berechnungen.

Ausgearbeitetes Beispiel: vier Tests decken alle zwölf Paare ab

Dieses fiktive Modell hat drei Faktoren: Browser (Chrome oder Firefox), Oberflächensprache (ru oder en) und Kontorolle (viewer oder editor). Alle acht Kombinationen sind erlaubt. Browserversionen, Betriebssystem, Datensatz und Feature-Flags bleiben während der Übung unverändert; bei einem echten Browsertest ihre genauen Werte dokumentieren. Dies ist ein Modell zur Eingabeauswahl, keine ausführbare Webanwendung.

Vollständige Kombinationsabdeckung benötigt 2 × 2 × 2 = 8 Zeilen. Paarweises Testen verlangt jedes Wertepaar aus zwei verschiedenen Faktoren: vier Browser-Sprach-Paare, vier Browser-Rollen-Paare und vier Sprach-Rollen-Paare. Die folgenden vier Zeilen decken diese zwölf Paare ab.

plain text
ID	Browser	Gebietsschema	Rolle
PW1	Chrome	ru	viewer
PW2	Chrome	en	editor
PW3	Firefox	ru	editor
PW4	Firefox	en	viewer

Die Abdeckung prüfen, statt der Zeilenanzahl zu vertrauen

plain text
Faktor A	Faktor B	Abgedeckt durch
Browser=Chrome	Locale=ru	PW1
Browser=Chrome	Locale=en	PW2
Browser=Firefox	Locale=ru	PW3
Browser=Firefox	Locale=en	PW4
Browser=Chrome	Role=viewer	PW1
Browser=Chrome	Role=editor	PW2
Browser=Firefox	Role=viewer	PW4
Browser=Firefox	Role=editor	PW3
Locale=ru	Role=viewer	PW1
Locale=ru	Role=editor	PW3
Locale=en	Role=viewer	PW4
Locale=en	Role=editor	PW2

Jede Tabellenzeile nennt ein erforderliches Paar und den Test, der es enthält. Die Tabelle deckt jedes Paar einmal ab. Vier Tests sind für dieses binäre Modell ohne Einschränkungen minimal: Schon die vier Browser-Sprach-Paare benötigen mindestens vier Zeilen. Diese Aussage gilt nur für dieses konkrete Modell, nicht für beliebige paarweise Testsuiten.

Die Matrix mit Python 3 überprüfen

Diesen Code in pairwise_coverage.py kopieren und python3 pairwise_coverage.py ausführen. Er verwendet nur die Standardbibliothek und führt keine Netzwerkanfragen aus. Erwartete Ausgabe: Pairs: 12/12; triples: 4/8.

plain text
from itertools import product, combinations
levels = [("Chrome", "Firefox"), ("ru", "en"), ("viewer", "editor")]
rows = [
    ("Chrome", "ru", "viewer"),
    ("Chrome", "en", "editor"),
    ("Firefox", "ru", "editor"),
    ("Firefox", "en", "viewer"),
]
required = {(i, a, j, b) for i, j in combinations(range(3), 2)
            for a, b in product(levels[i], levels[j])}
covered = {(i, row[i], j, row[j]) for row in rows
           for i, j in combinations(range(3), 2)}
assert all(row in set(product(*levels)) for row in rows)
assert covered == required
assert ("Chrome", "en", "viewer") not in rows
print(f"Pairs: {len(covered)}/{len(required)}; triples: {len(set(rows))}/8")

Für jede Konfiguration ein Verhaltensorakel festlegen

Bei einer fiktiven Dokumentfunktion die Regel vor der Ausführung definieren: Ein viewer darf lesen, aber ein Bearbeitungsversuch lässt den gespeicherten Inhalt unverändert; ein editor darf eine gültige Änderung genau einmal speichern. In jeder Matrixzeile die gewählte Sprache, das rollenspezifische Ergebnis und die gespeicherten Daten prüfen. Paarabdeckung allein belegt diese Ergebnisse nicht; eine bestandene Konfiguration ist ohne Ergebnisprüfungen kein Nachweis.

Ein Fehler, der nur durch Chrome + en + viewer ausgelöst wird, bleibt in dieser Matrix unentdeckt: Diese Dreierkombination fehlt, obwohl alle ihre Paare anderswo vorkommen. Die Kombination ergänzen, wenn Risiko oder ein früherer Fehler dies rechtfertigen. Ablauf-, Grenzwert-, Berechtigungs- und Leistungstests brauchen weiterhin einen eigenen Entwurf. Aus „12/12 Paaren“ folgt kein Prozentsatz gefundener Fehler.

Macht eine Produktbeschränkung eine Kombination unmöglich, zuerst erlaubte vollständige Kombinationen erzeugen, daraus erreichbare Paare ableiten und anschließend die reduzierte Suite neu erzeugen und prüfen. Das bloße Löschen einer ungültigen Zeile kann andere gültige Paare entfernen. Übung: PW4 entfernen; nicht abgedeckt sind dann Firefox–en, Firefox–viewer und en–viewer. Eine gültige abdeckende Zeile wiederherstellen, statt den Nenner stillschweigend zu reduzieren.

Weiterlernen

Zusätzliche Fälle nach Risiko auswählen

Browserübergreifende Prüfungen planen

NIST: kombinatorisches Testen und Interaktionsabdeckung