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.
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.
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.
// 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.


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.