Journal
Technik3 Min. Lesezeit

Die Pixel testen: Screenshot-QA für ein kleines Team

Unsere Tests waren grün und das Dropdown ließ sich nicht anklicken. Unit-Tests sehen keine Stapelfehler, kein kaputtes dunkles Theme und kein Überlaufen auf dem Handy. Hier ist die kleine Screenshot-Vorrichtung, die jetzt jede Oberfläche für uns anschaut, und die sichtbaren Fehler, die Tests nie finden.

DBDas Bookatu-Technikteam

Wir sind auf die ehrliche Art dazu gekommen: nachdem wir Rückschritte ausgeliefert hatten, die ein einziger Screenshot gefangen hätte. Ein Milchglas-Panel, das auf dunklem Grund blass herauskam. Ein Menü, das gerendert wurde, sich aber nicht anklicken ließ. Ein Suchfeld, das in Handybreite als 65 Pixel breiter Splitter existierte. Jeder einzelne davon ist durch eine grüne Testsuite gesegelt, weil die Suite Funktionen geprüft hat und die Fehler in den Pixeln wohnten.

Die Vorrichtung ist kleiner, als du denkst

Unsere ist eine befüllte lokale Umgebung voller überzeugender erfundener Daten, ein Headless-Login, dessen Sitzung auf der Platte liegt, damit nichts ausgebremst wird, und eine Schleife: Seiten mal Themes mal Bildschirmbreiten. Desktop und Handy, hell und dunkel, jede Oberfläche, auf die es ankommt. Das Ganze ist ein kurzes Skript, und ein voller Durchlauf erzeugt in ein paar Minuten einen Ordner voller Bilder.

js
import { chromium } from 'playwright'; const browser = await chromium.launch();const ctx = await browser.newContext({  storageState: 'auth.json', // login once, reuse everywhere  viewport: { width: 1440, height: 900 },});const page = await ctx.newPage(); for (const [name, url] of PAGES) {  await page.goto(BASE + url, { waitUntil: 'load' });  for (const theme of ['light', 'dark']) {    await page.evaluate((t) =>      document.documentElement.setAttribute('data-theme', t), theme);    await page.screenshot({ path: `shots/${name}-${theme}.png`, fullPage: true });  }}

Screenshots plus Beweis

Bilder fangen, was Augen fangen. Für Fehler bei der Bedienung willst du, dass der Browser aussagt. Zwei Einzeiler machen die meiste Arbeit: elementFromPoint in der Mitte eines Bedienelements sagt dir, was den Klick wirklich bekäme, und getBoundingClientRect sagt dir, ob das Element tatsächlich in die Bildschirmbreite passt, die es zu unterstützen behauptet. Wir prüfen inzwischen beides für alles, was uns schon einmal verbrannt hat.

js
// Is the menu item really clickable, or is something invisible covering it?const hit = await page.evaluate(() => {  const el = document.querySelector('[role="menuitem"]');  const r = el.getBoundingClientRect();  const top = document.elementFromPoint(r.x + r.width / 2, r.y + r.height / 2);  return el === top || el.contains(top);}); // Does the search input actually fit a 390px phone?const fits = await page.evaluate(() => {  const r = document.querySelector('input[name="q"]').getBoundingClientRect();  return r.right <= window.innerWidth && r.width > 200;});

Beide Themes, jedes Mal

Fehler im dunklen Theme sind eine eigene Kategorie, weil sie sich vor Entwicklern verstecken, die in einem Theme arbeiten. Eine fest eingetragene fast weiße Fläche sieht auf einer hellen Seite gewollt aus und auf einer dunklen radioaktiv. Das Theme-Attribut im selben Seitenbesuch umzuschalten kostet eine Zeile und verdoppelt deine Abdeckung. Jede Oberfläche, die nicht in beiden Themes fotografiert wurde, gilt bei uns als ungetestet.

Ein Buchungs-Dashboard, fotografiert im hellen Theme
Dieselbe Seite, zweimal pro Durchlauf fotografiert. Hell...
Dasselbe Buchungs-Dashboard, fotografiert im dunklen Theme
...und dunkel. Fest eingetragene Farben können sich nicht verstecken, wenn es beide Bilder gibt.

Was sie findet

  • Fehler im Stapelkontext: gerendert, sichtbar und nicht anklickbar. Das sieht nur eine Trefferprüfung.
  • Lecks im Theme: helle Flächen, die auf dunklen Seiten leuchten, Diagramme, die verschwinden, Illustrationen mit eingebranntem Hintergrund.
  • Überlaufen auf dem Handy: fest sitzende Leisten über dem Inhalt, Eingabefelder zu Splittern beschnitten, Überschriften mitten im Satz abgeschnitten.
  • Text im Zusammenhang: die Abschneidung, der Widerspruch, der Satz, den kein Linter je bemängeln wird.

Nichts davon ersetzt die Unit-Suite. Die Suite beweist die Geldrechnung, die Screenshots beweisen, dass ein Mensch den Button erreicht, der sie auslöst. Ein kleines Team hat keine QA-Abteilung, aber ein Ordner mit frischen Screenshots, die vor jedem Release durchgesehen werden, ist eine ordentliche Nachahmung davon. Der Test ist das Hinschauen.

Tests bestanden ist eine Aussage über deine Funktionen. Der Screenshot ist eine Aussage über dein Produkt.

visuelle regressionstestsplaywright screenshotsheadless browser testsdark mode testenqa automatisierung
Willst du das umsetzen?

Bookatu gibt dir eine Buchungsseite in deinem eigenen Look, Anzahlungen, Mitgliedschaften, Gutscheine und Erinnerungen, mit 0 % Provision auf deine Buchungen.

Kostenlos starten