Test de pixels: schermafbeeldingen als QA voor een klein team
Onze testsuite stond op groen en het uitklapmenu was onklikbaar. Unittests zien geen stacking-bugs, geen kapot donker thema en geen overloop op mobiel. Dit is het kleine rig dat nu elk scherm voor ons fotografeert, en de visuele bugs die het vangt en tests nooit zullen vangen.
We namen dit op de eerlijke manier over: nadat we visuele regressies hadden geleverd die één schermafbeelding had gevangen. Een matglazen paneel dat bleek uitviel op donkere achtergronden. Een menu dat wel tekende maar niet aan te klikken was. Een zoekveld dat op telefoonbreedte bestond als een streepje van 65 pixel. Ze zeilden er allemaal doorheen langs een groene testsuite, want de suite testte functies en de bugs woonden in pixels.
Het rig is kleiner dan je denkt
Het onze is een gevulde lokale omgeving vol overtuigende verzonnen data, één headless login waarvan de sessie op schijf staat zodat er niets wordt afgeknepen, en een lus: pagina's maal thema's maal schermbreedtes. Desktop en telefoon, licht en donker, elk scherm dat ertoe doet. Het geheel is een kort script, en een volledige ronde levert in een paar minuten een map met afbeeldingen op.
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 }); }}Schermafbeeldingen plus bewijs
Afbeeldingen vangen wat ogen vangen. Voor bugs in de interactie wil je dat de browser getuigt. Twee regels doen het meeste werk: elementFromPoint in het midden van een bedieningselement vertelt je wat er echt op de klik zou reageren, en getBoundingClientRect vertelt je of dat element ook echt past op het scherm waarvan het zegt het te ondersteunen. We controleren nu allebei voor alles wat ons ooit gebrand heeft.
// 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;});Allebei de thema's, elke keer
Bugs in de donkere modus zijn een categorie op zich, want ze verstoppen zich voor ontwikkelaars die in één thema werken. Een hardgecodeerde bijna-witte vulling ziet er bedoeld uit op een lichte pagina en radioactief op een donkere. Het themakenmerk omzetten binnen hetzelfde paginabezoek kost één regel en verdubbelt je dekking. Elk scherm dat niet in allebei de thema's is gefotografeerd, behandelen wij als ongetest.


Wat het vangt
- Bugs met stacking contexts: getekend, zichtbaar en onklikbaar. Alleen een hit-test ziet die.
- Lekkende thema's: lichte vlakken die oplichten op donkere pagina's, grafieken die verdwijnen, illustraties met een ingebakken achtergrond.
- Overloop op de telefoon: vaste balken die inhoud bedekken, invoervelden teruggeknipt tot streepjes, koppen die middenin een zin worden afgesneden.
- Tekst in context: de afkapping, de tegenspraak, de zin die een linter nooit zal aanwijzen.
Niets hiervan vervangt de unittests. De suite bewijst dat het rekenwerk met geld klopt, de schermafbeeldingen bewijzen dat een mens bij de knop kan die dat rekenwerk start. Een klein team heeft geen QA-afdeling, maar een map met verse schermafbeeldingen die je voor elke release doorloopt is een aardige imitatie ervan. De test is het kijken.
Tests slagen is een uitspraak over je functies. De schermafbeelding is een uitspraak over je product.