Ein Flaky Test (oder instabiler Test) ist ein Test, der unterschiedliche Ergebnisse liefert -- Erfolg oder Fehler -- für denselben Code und dieselbe Konfiguration, ohne dass eine Änderung am getesteten System vorgenommen wurde.
Hier eine Meinung, die Sie vielleicht stört: Ein flaky visueller Test ist schlimmer als gar kein Test. Und das ist keine leere Provokation. Ein fehlender Test kostet im Alltag nichts. Er blockiert nicht Ihre Pipeline. Er verbraucht nicht die Zeit Ihres Teams. Er zerstört nicht das Vertrauen in Ihre Testinfrastruktur. Ein Flaky Test tut all das, jeden Tag, und er tut es schleichend -- weil jeder Fehlalarm einem echten Fehler gerade genug ähnelt, um eine Untersuchung zu erfordern.
Die Daten von Google zu ihren eigenen Testsystemen sind aufschlussreich: Etwa 1,5 % ihrer Tests sind zu jedem Zeitpunkt flaky, aber diese Tests verbrauchen einen überproportionalen Anteil der Engineering-Zeit. Wenn ein Unternehmen von der Größe und technischen Kompetenz von Google das Problem nicht eliminiert hat, ist die Frage nicht trivial. Und im speziellen Bereich des visuellen Testings wird das Problem durch die Natur dessen, was verglichen wird, verstärkt.
Warum visuelle Tests besonders anfällig für Instabilität sind
Automatisiertes visuelles Testing führt eine Schicht von Nichtdeterminismus ein, die Unit- oder funktionale Tests nicht kennen. Ein Unit-Test prüft, ob eine Funktion den richtigen Wert zurückgibt. Ein funktionaler Test prüft, ob ein Button die richtige Aktion auslöst. Diese Ergebnisse sind binär und deterministisch -- die Funktion gibt 42 zurück oder nicht, der Button navigiert zur richtigen Seite oder nicht.
Visuelles Testing dagegen prüft, ob das Rendering Ihrer Oberfläche einem Referenzbild entspricht. Und das Rendering einer Webseite ist das Ergebnis einer Kette komplexer Prozesse, von denen jeder seine eigene Variabilität einführt: HTML-Parsing, CSS-Anwendung, JavaScript-Ausführung, Laden externer Ressourcen, Layout-Berechnung, Rasterisierung, Compositing. Jede Phase hängt von Faktoren ab, die von Ausführung zu Ausführung variieren.
Ein funktionaler Test, der prüft, ob der Button "In den Warenkorb" funktioniert, ist unempfindlich gegenüber der Tatsache, dass der Button 0,3 Pixel nach rechts gewandert ist. Ein visueller Test erkennt das. Und diese Erkennung ist manchmal ein echtes Positiv (der Button hat sich wegen eines CSS-Bugs bewegt), manchmal Rendering-Rauschen ohne Bedeutung. Genau diese Ambiguität macht visuelle Tests flaky.
Die vier Hauptursachen für flaky visuelle Tests
Timing: Das Problem, das Sie nicht ignorieren können
Das Web ist von Natur aus asynchron. Wenn Sie den Browser bitten, einen Screenshot zu erfassen -- ist die Seite tatsächlich fertig? Die Antwort ist fast immer: Es kommt darauf an.
Das Laden einer Webseite ist kein einzelnes Ereignis -- es ist eine Kaskade von Ereignissen. HTML wird geparst, CSS angewendet, Skripte ausgeführt, Bilder geladen, Web-Fonts angewendet, API-Anfragen geben Daten zurück, Komponenten werden gerendert. Jede Phase hat eine variable Dauer. Eine API-Anfrage, die normalerweise 50 ms dauert, kann 300 ms dauern, wenn der Server unter Last steht. Ein Bild, das in 100 ms lädt, kann 2 Sekunden brauchen, wenn das Netzwerk langsam ist.
Die klassische Strategie ist, zu warten, bis die Seite "bereit" ist -- das DOMContentLoaded-Event, das load-Event oder die Abwesenheit von Netzwerkaktivität. Aber keines dieser Signale garantiert, dass das visuelle Rendering vollständig ist. Das load-Event wird ausgelöst, wenn die initialen Ressourcen geladen sind, aber clientseitig per JavaScript gerenderte Komponenten können sich danach noch weiter laden. Die Abwesenheit von Netzwerkaktivität bedeutet nicht, dass alle Elemente gezeichnet sind -- der Browser kann noch Layout berechnen oder komplexe Elemente rasterisieren.
Ergebnis: Ihr Screenshot erfasst manchmal eine vollständige Seite, manchmal eine Seite im Rendering-Vorgang. Derselbe Test besteht am Montag und schlägt am Dienstag fehl, ohne jeden codebezogenen Grund.
Animationen: Bewegung in einem statischen Medium
Ein Screenshot ist ein Standbild. Eine Animation ist eine kontinuierliche Veränderung. Beide sind fundamental inkompatibel für den automatisierten Vergleich. Wir haben dieses Problem in unserem Leitfaden zu CSS-Animationen und visuellem Testing detailliert beschrieben, aber hier das Wesentliche.
Wenn Ihre Seite eine 300-ms-Animation enthält, die beim Laden startet, variiert der exakte Zeitpunkt der Screenshot-Erfassung relativ zum Start dieser Animation von Ausführung zu Ausführung. Bei 100 ms ist das Element bei einem Drittel seiner Animation. Bei 200 ms bei zwei Dritteln. Beide Screenshots sind "korrekt" -- sie spiegeln getreu den Zustand der Seite zum Zeitpunkt der Erfassung wider -- aber sie sind visuell unterschiedlich, und das Vergleichstool meldet einen Fehler.
Endlosanimationen (Spinner, Skeleton Loader, Fortschrittsanzeigen) sind noch schlimmer: Es gibt keinen "stabilen" Moment für die Screenshot-Erfassung, weil das Element in permanenter Bewegung ist.
Dynamischer Inhalt: Alles, was sich ohne Ihr Zutun ändert
Die Datums- und Uhrzeitangaben in Ihrer Oberfläche ändern sich jede Sekunde. Werbung rotiert nach Algorithmen, die Sie nicht kontrollieren. Zufällig generierte Avatare sind bei jeder Sitzung anders. Echtzeitbenachrichtigungen erscheinen unvorhersehbar. Online-Besucherzähler, "Neu"-Badges, personalisierte Willkommensnachrichten -- all dieser Inhalt variiert zwischen zwei Testausführungen.
Jede Variation wird als visueller Unterschied erkannt. Jeder Unterschied lässt den Test fehlschlagen. Und da diese Variationen keine Bugs sind, ist jeder Fehler ein Fehlalarm -- ein flaky Ergebnis, das Ihre Zeit verbraucht, ohne etwas beizutragen.
Dynamischer Inhalt ist besonders tückisch, weil er oft über die gesamte Seite verteilt ist. Es ist nicht ein isoliertes Element, das Sie leicht ausschließen können -- es ist ein Datum im Header, ein Zähler in der Sidebar, ein Zeitstempel in jeder Nachricht eines Threads.
Netzwerk und Infrastruktur: Die Variablen, die Sie nicht kontrollieren
Ihr Test läuft in einer Umgebung ab, die von externen Ressourcen abhängt: API-Server, CDN für Bilder und Fonts, Drittanbieterdienste für Widgets und Analytics. Die Latenz jeder dieser Ressourcen variiert von Ausführung zu Ausführung.
In einer CI/CD-Pipeline wird das Problem verstärkt. Ihr CI-Runner teilt Ressourcen mit anderen Jobs. Die verfügbare CPU-Last variiert. Der Speicher schwankt. Das Netzwerk zwischen dem Runner und Ihren Servern nimmt je nach Tageszeit unterschiedliche Routen. All diese Faktoren beeinflussen die Rendering-Zeit der Seite und damit den visuellen Zustand zum Zeitpunkt der Erfassung.
Ein Test, der auf dem Entwicklerrechner systematisch besteht, kann in der CI intermittierend fehlschlagen, einfach weil die CI-Umgebung weniger vorhersehbar ist. Das ist frustrierend und äußerst häufig.
Die realen Kosten von Flaky Tests
Die sichtbarsten Kosten sind die Triage-Zeit. Jeder flaky Test, der in der CI fehlschlägt, erfordert eine Untersuchung: Jemand muss die Ergebnisse anschauen, manuell vergleichen, entscheiden, ob es ein echter Bug oder Rauschen ist, und die Pipeline bei Bedarf neu starten. Bei 5 bis 15 Minuten pro Untersuchung, und mehreren flaky Fehlern pro Tag, akkumuliert sich die Zeit schnell.
Aber die zerstörerischsten Kosten sind unsichtbar: der Vertrauensverlust. Wenn ein Team lernt, dass visuelle Tests "ständig" ohne Grund fehlschlagen, entwickelt es einen automatischen Neustartreflex. "Der visuelle Test ist fehlgeschlagen? Neustart, wird schon gehen." Dieser Reflex ist rational -- meistens reicht ein Neustart. Aber am Tag, an dem der Test wegen eines echten Bugs fehlschlägt, ist der Reflex derselbe: Neustart. Und der Bug gelangt in Produktion.
Dieses Phänomen hat in der Literatur zur Softwarezuverlässigkeit einen Namen: der "Cry Wolf"-Effekt, nach der Fabel vom Jungen, der Wolf schrie. Einmal installiert, ist er sehr schwer umzukehren. Einmal verlorenes Vertrauen in eine Testsuite braucht Monate zur Wiederherstellung -- wenn es überhaupt wiederhergestellt wird.
Es gibt auch Opportunitätskosten. Die Zeit, die Ihr Team mit dem Management von Flaky Tests verbringt, ist Zeit, die es nicht damit verbringt, neue Tests zu schreiben, die Abdeckung zu verbessern oder echte Bugs zu beheben. Flaky Tests sind nicht nur ein Problem -- sie sind eine aktive Bremse für die Verbesserung Ihrer Softwarequalität.
Stabilisierungsstrategien, die funktionieren
Die Rendering-Umgebung kontrollieren
Die erste Verteidigungslinie ist die Minimierung der Umgebungsvariabilität. Verwenden Sie einen Headless-Browser in einem kontrollierten Container mit fester Auflösung, vorinstallierten Fonts und deterministischer Netzwerkkonfiguration. Das löst nicht alles, eliminiert aber eine ganze Kategorie von Variabilität.
Konkret bedeutet das: Browserversion einfrieren, alle von Ihrer Anwendung verwendeten Fonts im Container installieren, GPU-Rendering deaktivieren (das Nichtdeterminismus einführt) und einen Viewport fester Größe konfigurieren. Es ist eine initiale Investition, die sich schnell amortisiert.
Animationen neutralisieren
Injizieren Sie ein Stylesheet, das alle Animationen und Transitions auf null Dauer zwingt. Das friert sofort alle animierten Elemente in ihrem Endzustand ein und eliminiert das Timing-Problem. Die meisten visuellen Testing-Frameworks bieten diese Option, und sie sollte standardmäßig in allen visuellen Tests aktiviert sein.
Vorsicht jedoch: Einige Animationen sind funktional (ein Karussell, das Inhalt anzeigt, ein Accordion, das einen Bereich aufklappt). Sie zu deaktivieren kann Teile der Oberfläche verbergen. Für diese Fälle warten Sie, bis die Animation ihren Endzustand erreicht hat, statt sie zu deaktivieren.
Dynamischen Inhalt stabilisieren
Für Inhalt, der sich bei jedem Laden ändert, gibt es je nach Kontext mehrere Optionen.
Daten und Uhrzeiten können eingefroren werden, indem die Testumgebung mit einem festen Datum konfiguriert wird. Werbung und Drittanbieter-Widgets können in der Testumgebung deaktiviert werden. API-Daten können gemockt werden, um konstante Antworten zu liefern. Generierte Avatare können in den Test-Fixtures durch statische Bilder ersetzt werden.
Das Ziel ist, eine Testumgebung zu schaffen, in der der einzige variable Faktor der Code Ihrer Oberfläche ist -- alles andere ist kontrolliert.
Intelligent warten
Statt sich auf eine feste Verzögerung zu verlassen (3 Sekunden nach dem Laden warten), verwenden Sie Wartestrategien basierend auf dem tatsächlichen Seitenzustand. Warten Sie, bis kritische Elemente sichtbar sind, Bilder geladen sind, Fonts angewendet sind und Netzwerkanfragen abgeschlossen sind.
Moderne Browser und Automatisierungstools bieten APIs zur Beobachtung des DOM- und Netzwerkzustands. Nutzen Sie sie, um präzise Stabilitätsbedingungen zu definieren, statt willkürliche Verzögerungen zu verwenden.
Einen rauschtoleranten Vergleich einsetzen
Der Pixel-für-Pixel-Vergleich ist am empfindlichsten gegenüber Rendering-Nichtdeterminismus. Perzeptuelle Algorithmen (SSIM, pHash) sind toleranter. Der strukturelle Ansatz -- DOM und berechnete CSS-Eigenschaften vergleichen statt Pixel -- ist am widerstandsfähigsten gegenüber Rendering-Rauschen, weil er naturbedingt die Sub-Pixel-Variationen ignoriert, die die Mehrheit der flaky Fehler verursachen.
No-Code visuelles Testing als Lösung für das Wartungsproblem
Ein oft übersehener Aspekt des Flaky-Problems ist die Wartung. Codebasierte visuelle Tests (Playwright, Cypress, Selenium) erfordern Skripte, die zur Seite navigieren, mit Elementen interagieren und den Screenshot erfassen. Die Zuverlässigkeit dieser Testsuite hängt direkt von der Stabilität jedes einzelnen Skripts ab. Diese Skripte sind selbst eine Quelle von Instabilität: Ein CSS-Selektor, der das Element nicht mehr findet, ein Klick-Timing, das sein Ziel verfehlt, eine Assertion, die fehlschlägt, weil sich der Text geändert hat.
No-Code-Tools wie Delta-QA eliminieren diese Fragilitätsschicht. Sie schreiben keine Skripte -- Sie konfigurieren Ihre Tests visuell. Das Tool übernimmt das Laden, Warten, Stabilisieren und Vergleichen. Wenn ein Element seinen Selektor ändert, passt sich das Tool ohne Eingriff an. Wenn sich das Layout weiterentwickelt, aktualisieren Sie die Baseline mit einem Klick statt Code zu ändern.
Es ist eine andere Philosophie: Statt fragile Tests zu coden, die Sie ständig reparieren müssen, konfigurieren Sie visuelle Überprüfungen, die das Tool für Sie pflegt.
Wann man einen Flaky Test entfernen sollte
Wenn ein visueller Test trotz aller Stabilisierungsversuche intermittierend fehlschlägt, ist die mutigste -- und oft weiseste -- Entscheidung, ihn zu entfernen. Ein Flaky Test, den niemand korrigiert, ist ein Test, der Ihre Pipeline aktiv verschlechtert. Er trainiert Ihr Team, Fehler zu ignorieren. Er erzeugt Rauschen, das echte Probleme überdeckt.
Entfernen Sie ihn, dokumentieren Sie warum, und ersetzen Sie ihn durch eine gezieltere Überprüfung. Manchmal ist ein funktionaler Test, der prüft, ob das Element vorhanden und korrekt positioniert ist (über das DOM), zuverlässiger als ein Screenshot-Vergleich einer instabilen Komponente.
Das Ziel ist nicht, die maximale Anzahl von Tests zu haben -- es ist, Tests zu haben, denen Ihr Team vertraut.
FAQ
Was ist der Unterschied zwischen einem Flaky Test und einem False Positive?
Ein False Positive ist ein Testergebnis, das ein Problem meldet, das nicht existiert -- ein einzelnes Vorkommen genügt. Ein Flaky Test ist ein Test, der inkonsistente Ergebnisse von einer Ausführung zur nächsten für denselben Code liefert. Ein Flaky Test erzeugt intermittierend False Positives. Alle Flaky Tests erzeugen False Positives, aber nicht alle False Positives stammen von Flaky Tests -- manche sind systematisch.
Wie messe ich die Flakiness-Rate meiner visuellen Tests?
Die einfachste Methode: Starten Sie dieselbe visuelle Testsuite mehrmals hintereinander, ohne den Code zu ändern, und zählen Sie die Tests, deren Ergebnis sich zwischen den Ausführungen ändert. Fünf aufeinanderfolgende Ausführungen genügen, um die instabilsten Tests zu identifizieren. Teilen Sie die Anzahl der Tests mit variierendem Ergebnis durch die Gesamtanzahl der Tests, um Ihre Flakiness-Rate zu erhalten.
Sind No-Code visuelle Tests weniger flaky als codierte Tests?
Sie eliminieren eine Kategorie von Flakiness -- die der Testskripte selbst (fragile Selektoren, Navigations-Timing, Zustandsmanagement). Aber sie unterliegen denselben Browser-Rendering-Einschränkungen wie codierte Tests. Der Hauptvorteil ist die Reduzierung der Fragilitätsoberfläche: weniger Code, weniger potenzielle Fehlerpunkte.
Sollte man fehlgeschlagene visuelle Tests automatisch neu starten?
Automatische Neustarts (Retry) sind ein Pflaster, keine Lösung. Sie überdecken das Flakiness-Problem, statt es zu lösen. Wenn Sie Retries aktivieren müssen, beschränken Sie sie auf einen einzelnen Neustart und markieren Sie Tests, die einen Neustart benötigt haben, zur Untersuchung. Ein Test, der nur beim zweiten Versuch besteht, ist ein Flaky Test, der auf Korrektur wartet.
Welche Flakiness-Schwelle ist in CI/CD akzeptabel?
Streben Sie eine Flakiness-Rate unter 1 % Ihrer gesamten Testsuite an. Über 3 % wird der Produktivitätseinfluss messbar. Über 5 % entwickelt Ihr Team mit ziemlicher Sicherheit den Reflex, fehlgeschlagene Pipelines systematisch neu zu starten, was bedeutet, dass Ihre Testsuite ihre Glaubwürdigkeit als Sicherheitsnetz verloren hat.
Hilft Delta-QA bei der Stabilisierung visueller Tests?
Delta-QA reduziert Flakiness an der Quelle, indem es einen strukturellen statt eines Pixel-für-Pixel-Ansatzes verwendet. Die Sub-Pixel-Rendering-Variationen, Antialiasing und Timing-Schwankungen, die die Mehrheit der intermittierenden Fehler verursachen, werden nativ ignoriert. Kombiniert mit dem No-Code-Ansatz, der fragile Testskripte eliminiert, liefert Delta-QA zuverlässige und reproduzierbare Testergebnisse ohne komplexe Konfiguration.
Weiterführende Lektüre
- DevOps und Visuelles Testing: Shift-Left der visuellen Qualität in Ihrer Pipeline
- Baseline-Verwaltung im Visuellen Testing: Best Practices, Die Den Unterschied Machen
Ein visueller Test hat nur Wert, wenn Ihr Team ihm vertraut. Flaky Tests zerstören dieses Vertrauen Tag für Tag. Statt Ihre Zeit mit der Stabilisierung fragiler Skripte und dem Sortieren von Fehlalarmen zu verbringen, setzen Sie ein Tool ein, das von Anfang an für Zuverlässigkeit konzipiert wurde.