Dziennik
Technologia2 min czytania

Testuj piksele: kontrola jakości na zrzutach ekranu w małym zespole

Nasze testy świeciły na zielono, a rozwijanego menu nie dało się kliknąć. Testy jednostkowe nie widzą błędów nakładania, rozsypanego trybu ciemnego ani przepełnienia na telefonie. Oto mała maszynka do zrzutów ekranu, która ogląda teraz za nas każdą powierzchnię, i wizualne błędy, których testy nigdy nie złapią.

ZIZespół inżynierów Bookatu

Przyjęliśmy to uczciwą drogą: po wypuszczeniu wizualnych regresji, które złapałby jeden zrzut ekranu. Matowy panel, który na ciemnym tle wyszedł blady. Menu, które się renderowało, ale nie dawało się kliknąć. Pole wyszukiwania, które przy szerokości telefonu istniało jako 65-pikselowy pasek. Każde z nich przepłynęło przez zieloną paczkę testów, bo paczka testowała funkcje, a błędy mieszkały w pikselach.

Ta maszynka jest mniejsza, niż myślisz

Nasza to zasiane lokalne środowisko pełne przekonujących wymyślonych danych, jedno logowanie w trybie headless, którego sesja jest zapisana na dysk, żeby nic nie dławiło ruchu, i pętla: strony razy motywy razy rozmiary okna. Komputer i telefon, jasny i ciemny, każda powierzchnia, która ma znaczenie. Całość to krótki skrypt, a pełne przejście produkuje folder obrazów w kilka minut.

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 });  }}

Zrzuty plus dowód

Obrazy łapią to, co łapią oczy. Przy błędach interakcji chcesz, żeby zeznawała przeglądarka. Dwie jednolinijkowe rzeczy robią większość roboty: elementFromPoint w środku kontrolki mówi, co naprawdę odebrałoby kliknięcie, a getBoundingClientRect mówi, czy kontrolka faktycznie mieści się w oknie, które rzekomo obsługuje. Sprawdzamy teraz oba dla wszystkiego, co nas kiedyś sparzyło.

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;});

Oba motywy, za każdym razem

Błędy trybu ciemnego to osobna kategoria, bo ukrywają się przed programistami pracującymi w jednym motywie. Zaszyte na sztywno prawie białe wypełnienie wygląda na zamierzone na jasnej stronie i promieniotwórczo na ciemnej. Przełączenie atrybutu motywu w tej samej wizycie na stronie kosztuje jedną linię i podwaja pokrycie. Każdą powierzchnię, która nie została sfotografowana w obu motywach, traktujemy jako nieprzetestowaną.

Panel rezerwacji sfotografowany w jasnym motywie
Ta sama strona, fotografowana dwa razy na przejście. Jasny...
Ten sam panel rezerwacji sfotografowany w ciemnym motywie
...i ciemny. Zaszyte na sztywno kolory nie mają się gdzie ukryć, gdy istnieją oba kadry.

Co to łapie

  • Błędy kontekstu nakładania: wyrenderowane, widoczne i nieklikalne. Widzi je tylko test trafienia.
  • Przecieki motywu: jasne powierzchnie świecące na ciemnych stronach, znikające wykresy, ilustracje z wypalonym tłem.
  • Przepełnienie na telefonie: przypięte paski zasłaniające treść, pola przycięte do paseczków, nagłówki ucięte w połowie zdania.
  • Tekst w kontekście: ucięcie, sprzeczność, zdanie, którego żaden linter nigdy nie oznaczy.

Nic z tego nie zastępuje testów jednostkowych. Testy dowodzą, że matematyka pieniędzy się zgadza, a zrzuty dowodzą, że człowiek dosięgnie przycisku, który ją uruchamia. Mały zespół nie ma działu kontroli jakości, ale folder świeżych zrzutów przeglądany przed każdym wydaniem jest jego przyzwoitą imitacją. Testem jest patrzenie.

Testy przechodzą to zdanie o Twoich funkcjach. Zrzut ekranu to zdanie o Twoim produkcie.

testy regresji wizualnejzrzuty ekranu w playwrighttesty w przeglądarce headlesstestowanie trybu ciemnegoautomatyzacja qa
Gotowy, żeby to wykorzystać?

Bookatu daje Ci firmową stronę rezerwacji, zadatki, karnety, karty podarunkowe i przypomnienia, przy 0% prowizji od Twoich rezerwacji.

Zacznij za darmo