Leitfaden für visuelle Regressionstests

Visuelle Regressionstests ohne unzuverlässiges Screenshot-Rauschen

Kurz erklärt

Ein visueller Regressionstest stellt einen bekannten Seitenzustand her, nimmt ihn auf und vergleicht das Bild mit einer freigegebenen Baseline. Ein brauchbarer Test fixiert vorher Viewport, Daten, Schriften und Animationen. Der Diff liefert dann Belege für ein Review, statt jedes veränderte Pixel automatisch zum Fehler zu erklären.

Geprüft von RenderLog ProduktteamAktualisiert
Visueller Vergleich in RenderLog mit freigegebener Baseline, aktueller Aufnahme und hervorgehobenen Änderungen

Ein Screenshot wird erst dann zum Test, wenn das Team sagen kann, welchen Zustand er zeigt, wie dieser Zustand erneut hergestellt wird und wer eine Abweichung bewertet. Das Bild von gestern vom Bild von heute abzuziehen ist technisch einfach. Die eigentliche Arbeit liegt darin, beide Aufnahmen unter vergleichbaren Bedingungen zu erzeugen und anschließend eine nachvollziehbare Entscheidung zu treffen.

Dieser Leitfaden verwendet eine Preisseite als durchgehendes Beispiel. Dort treffen Layout, Live-Daten, Texte und eine geschäftskritische Entscheidung aufeinander. Dieselbe Methode passt zu Checkout, Registrierung, Dokumentation, Kontoeinstellungen und Kundendashboards. Außerdem wird deutlich, wann ein Test im Repository, eine Screenshot-API oder ein gemeinsamer Review-Prozess in RenderLog sinnvoll ist.

Mit einem reproduzierbaren Zustand beginnen, nicht mit vielen Screenshots

Beschreiben Sie den Zustand, bevor Sie ein Werkzeug auswählen. Für eine Preisseite können das ein Viewport von 1440 mal 1000 Pixeln, helles Farbschema, deutsche Sprache, UTC, ein abgemeldeter Nutzer und eine feste Antwort des Preis-Endpunkts sein. Die Seite ist erst bereit, wenn Überschrift und alle Tarifkarten sichtbar sind. Eine frühere Aufnahme belegt nicht denselben Zustand.

Jeder dynamische Bereich braucht eine bewusste Regel. Frieren Sie ein Datum oder einen Preis ein, wenn der Wert nicht geprüft wird. Maskieren Sie einen Chat-Launcher nur dann, wenn er nichts mit der Aussage des Tests zu tun hat. Warten Sie auf ein Diagramm, wenn es zum Ergebnis gehört. Verstecken Sie nicht die ganze Karte wegen eines Zeitstempels. Jede Maske nimmt Abdeckung weg und sollte deshalb klein, benannt und im Test leicht auffindbar sein.

  • Viewport, Sprache, Zeitzone, Farbschema und Anmeldestatus festlegen.
  • Auf ein sichtbares Bereitschaftssignal statt auf eine feste Pause warten.
  • Instabile Daten nur ersetzen, wenn deren Wert nicht geprüft wird.
  • Masken und ignorierte Bereiche zusammen mit dem Check dokumentieren.

Eine Baseline ist eine Freigabe, nicht bloß der erste Lauf

Auch die erste technisch erfolgreiche Aufnahme kann eine fehlende Schrift, einen leeren Preis oder ein Consent-Banner über der Hauptaktion enthalten. Eine Person muss das vollständige Ergebnis prüfen, bevor es zur Baseline wird. Speichern Sie Aufnahme, Viewport, Seitenzustand und Freigabegrund zusammen. Sonst lässt sich später nicht erkennen, ob ein Unterschied aus einer geplanten Designänderung oder aus einer veränderten Umgebung stammt.

Wenn sich das Produkt absichtlich ändert, sollte die neue Baseline aus einem geprüften Ergebnis hervorgehen. Erzeugen Sie nach einem Release nicht blind alle Bilder neu. Ein Sammelbefehl ist schnell, kann aber genau die Regression bestätigen, die der Test finden sollte. Prüfen Sie betroffene Seiten in kleinen Gruppen und behalten Sie den vorherigen freigegebenen Zustand in der Historie.

  • Die erste Aufnahme vor der Freigabe vollständig ansehen.
  • Viewport und Seitenzustand als Metadaten speichern.
  • Nur ein geprüftes Ergebnis zur neuen Baseline machen.
  • Den vorherigen freigegebenen Zustand verfügbar halten.

Toleranzen sollen Rendering-Varianten abfangen, keine Produktänderungen

Eine Toleranz bestimmt, wie viel technische Bildabweichung der Vergleich zulässt. Sie entscheidet nicht, ob eine Änderung am Produkt akzeptabel ist. Leichte Unterschiede an geglätteten Buchstabenkanten können harmlos sein. Eine fehlende Tarifkarte, ein verrutschtes Feldlabel oder ein unsichtbarer Button ist es nicht, selbst wenn der betroffene Bereich auf einem langen Screenshot klein wirkt.

Beginnen Sie auf einem stabilen Browser und Runner streng. Sehen Sie sich die ersten Fehler an, bevor Sie den Grenzwert erhöhen. Liegen alle Unterschiede an Schriftkanten, gleichen Sie zuerst Browser und Fonts an. Wechselt ständig ein Video-Thumbnail oder Testimonial, stabilisieren oder maskieren Sie genau diesen Bereich. Eine globale Toleranz, die eine ganze Komponente verschluckt, verschluckt auch unabhängige Fehler daneben.

  • Geänderte Pixel als Hinweis für die Analyse, nicht als Release-Entscheidung nutzen.
  • Die Umgebung korrigieren, bevor die allgemeine Toleranz steigt.
  • Für eine kritische Komponente bei Bedarf eine eigene Aufnahme verwenden.
  • Einen nicht fertig gerenderten Lauf getrennt von einem visuellen Diff melden.

Die Testoberfläche nach der Verantwortung für das Ergebnis wählen

Ein Playwright- oder Cypress-Test gehört nahe an den Code. Er kann Daten vorbereiten, APIs simulieren und einen Pull Request blockieren. Das ist meist der richtige Ort für Komponenten und Release-Prüfungen, die Entwickler verantworten. Selenium bleibt sinnvoll, wenn bereits eine funktionale Suite oder ein Browser-Grid vorhanden ist und der Screenshot als weiteres Artefakt desselben Ablaufs entsteht.

Eine Screenshot-API reicht, wenn lediglich PNG, PDF oder ein Seitenbild erzeugt werden soll und ein anderes System Review und Vergleich übernimmt. RenderLog passt, wenn eine Seite eine freigegebene Baseline, wiederholte Läufe, sichtbare Diffs, Historie und Benachrichtigungen für Produkt, Marketing, Betrieb, Agentur oder Kunde braucht. Ein Team kann alle drei Ansätze einsetzen, sollte denselben Full-Page-Check aber nicht ohne benannten Besitzer mehrfach ausführen.

  • Komponentenchecks und Merge-Gates im Repository belassen.
  • Eine Screenshot-API nutzen, wenn das aufrufende System den Review besitzt.
  • Eine gemeinsame Oberfläche für geplante Seiten und mehrere Rollen einsetzen.
  • Doppelte Full-Page-Checks ohne unterschiedliche Entscheidung vermeiden.

Vor jeder Aktualisierung zuerst die Fehlerursache bestimmen

Ein brauchbarer Fehlschlag beantwortet drei Fragen: Was hat sich geändert, wurde die Seite fertig und welche Belege gibt es? Vergleichen Sie Baseline, aktuelle Aufnahme und Diff in derselben Größe. Prüfen Sie danach Status, Bereitschaftssignal, Browserprotokolle und Assertions. Ein leeres aktuelles Bild nach einem Timeout ist ein Laufzeitfehler. Eine vollständige Seite ohne Tarifkarte ist ein Produktunterschied. Beide Fälle dürfen nicht in derselben roten Meldung verschwinden.

Wiederkehrende Ursachen sollten benannt werden. Umgebungsrauschen verweist auf Browser, Fonts oder Datenaufbau. Ein unerwarteter Produktunterschied muss untersucht werden. Eine erwartete Änderung braucht eine Freigabe. Ein defekter Check braucht ein besseres Bereitschaftssignal oder einen genaueren Selektor. Diese Einteilung verhindert, dass Baselines so lange aktualisiert werden, bis niemand dem Test mehr vertraut.

  • Lauffehler: Seite oder Aufnahme wurde nicht fertiggestellt.
  • Umgebungsunterschied: Der Zustand ist nicht vergleichbar.
  • Unerwartete Produktänderung: Vor der Freigabe untersuchen.
  • Erwartete Produktänderung: Mit einem dokumentierten Grund freigeben.

Eine kleine Testsammlung bauen, die tatsächlich gepflegt wird

Starten Sie mit drei bis fünf Zuständen, deren Fehler einen klaren Besitzer hat: Preisseite, erfolgreiche Registrierung, Checkout-Zusammenfassung, eine wichtige Dokumentationsseite und ein repräsentativer mobiler Zustand. Führen Sie sie bei Releases oder in einem Rhythmus aus, der zu den Änderungen passt. Hundert unbeaufsichtigte Screenshots erzeugen mehr Rauschen als fünf Checks, die echte Entscheidungen unterstützen.

Prüfen Sie die Sammlung vierteljährlich. Entfernen Sie einen Check, wenn niemand auf Fehler reagiert. Teilen Sie eine Seite, wenn ein instabiler Bereich einen wichtigen stabilen Bereich verdeckt. Ergänzen Sie einen Zustand nach einem echten Defekt oder einer wiederkehrenden manuellen Prüfung, nicht nur weil eine weitere URL existiert. Gute Abdeckung folgt Risiko und Verantwortung, nicht der Länge der Sitemap.

  • Jedem Check einen Besitzer und einen nachvollziehbaren Zweck geben.
  • Desktop und Mobile nur dann getrennt abdecken, wenn beide relevant sind.
  • Fehler mit Release-, Kunden- oder Betriebsentscheidungen verbinden.
  • Checks entfernen, deren Ergebnis keine Handlung mehr verändert.

Welche Form des visuellen Testens passt zur Aufgabe?

Die Werkzeuge überschneiden sich bei der Aufnahme. Entscheidend sind die Kontrolle über den Seitenzustand, der Ort des Reviews und die Handlung nach einer Abweichung.

EntscheidungPlaywright, Cypress oder SeleniumScreenshot-APIRenderLog
Bester BesitzerEntwicklung und Code-ReviewAufrufende AnwendungProdukt, Betrieb, Agentur oder gemischtes Team
ZustandskontrolleFixtures, Mocks und Abläufe im CodeAnfrageoptionen und Client-LogikGespeicherte Checks, Szenarien, Zeitpläne und API-Läufe
ReviewCI-Artefakt oder Pull RequestMuss der Client bereitstellenBaseline, aktuelles Ergebnis, Diff und Laufhistorie
Geeignet wennDer Check Code blockieren sollNur die Datei benötigt wirdWiederholter Review und gemeinsame Verantwortung nötig sind

Minimale Beispiele für drei verbreitete Stacks

Die Beispiele zeigen den Aufnahmezeitpunkt, keine vollständige Produktionssuite. Ergänzen Sie reproduzierbare Daten, Aufbewahrung der Artefakte und einen benannten Review-Weg, bevor ein erster grüner Lauf als Abdeckung gilt.

Playwright

import { test, expect } from "@playwright/test";

test("pricing page visual baseline", async ({ page }) => {
  await page.goto("https://example.com/pricing");
  await page.getByRole("heading", { name: "Pricing" }).waitFor();
  await expect(page).toHaveScreenshot("pricing-desktop.png", {
    animations: "disabled",
    fullPage: true
  });
});

Cypress

describe("pricing page", () => {
  it("matches the approved state", () => {
    cy.visit("https://example.com/pricing");
    cy.contains("h1", "Pricing").should("be.visible");
    cy.matchImageSnapshot("pricing-desktop");
  });
});

Selenium

await driver.get("https://example.com/pricing");
const screenshot = await driver.takeScreenshot();
await writeFile("artifacts/pricing-current.png", screenshot, "base64");
// Compare the current image with an approved baseline in the same viewport.

Primärquellen für diesen Leitfaden

API-Details ändern sich. Prüfen Sie bei der Implementierung die offizielle Dokumentation und verwenden Sie diesen Leitfaden für Entscheidungen zu Reproduzierbarkeit, Verantwortung und Review.

Mit einem konkreten Ablauf weitermachen

Mit einer Seite beginnen, die bereits jemand manuell prüft

Erstellen Sie einen gespeicherten Check für eine Preisseite, Registrierung oder Kundenseite mit einem echten Besitzer. Geben Sie die erste Baseline erst frei, wenn Seitenzustand, Viewport und Daten reproduzierbar sind.

RenderLog-Arbeitsbereich erstellen