Посібник із візуального регресійного тестування

Візуальне регресійне тестування без шуму у знімках

Коротка відповідь

Візуальне регресійне тестування відтворює відомий стан сторінки, робить знімок і порівнює його з перевіреним базовим зображенням. Спочатку треба зафіксувати розмір вікна, дані, шрифти й анімації. Тоді різниця між знімками стає доказом для перевірки, а не хибним вироком кожному зміненому пікселю.

Перевірила команда RenderLogОновлено
Порівняння в RenderLog із базовим і поточним знімками та підсвіченими змінами інтерфейсу

Зображення стає тестом лише тоді, коли команда може пояснити, який стан воно показує, як цей стан повторити і хто вирішує, чи припустима зміна. Зберегти вчорашній знімок і відняти його від сьогоднішнього неважко. Складніша й важливіша частина роботи полягає в тому, щоб обидва результати справді можна було порівнювати.

У цьому посібнику наскрізним прикладом є сторінка тарифів. На ній одночасно присутні верстка, дані з API, текст і важливе для бізнесу рішення користувача. Та сама схема працює для оформлення замовлення, реєстрації, документації, налаштувань і клієнтських панелей. Також розберемо, коли достатньо Playwright, Cypress чи Selenium, коли потрібен API знімків, а коли корисні історія перевірок і спільне погодження в RenderLog.

Починайте з відтворюваного стану, а не з кількості знімків

Опишіть стан сторінки ще до вибору інструмента. Для тарифів це може бути вікно 1440 на 1000 пікселів, світла тема, українська мова, часовий пояс UTC, гість без активного сеансу та фіксована відповідь API з цінами. Сторінка готова до знімка лише тоді, коли видно заголовок і всі картки планів. Зображення, зроблене раніше, не є доказом того самого стану.

Для кожної динамічної ділянки потрібне окреме рішення. Зафіксуйте дату чи ціну, якщо вони не належать до предмета перевірки. Сховайте лише віджет чату, коли він перекриває сторінку, але не впливає на результат. Дочекайтеся графіка, якщо він важливий. Не закривайте маскою всю картку через один часовий штамп: кожна маска забирає частину покриття, тому має бути вузькою, названою й помітною у визначенні перевірки.

  • Зафіксуйте розмір вікна, мову, часовий пояс, тему й стан входу.
  • Чекайте на видиму ознаку готовності замість довільної затримки.
  • Підміняйте нестабільні дані лише тоді, коли не перевіряєте самі дані.
  • Зберігайте перелік масок і пропущених ділянок разом із перевіркою.

Базовий знімок є погодженим рішенням, а не просто першим запуском

Навіть перший успішний результат може містити незавантажений шрифт, порожню ціну або банер згоди, що закриває кнопку. Людина має оглянути всю сторінку до того, як вона стане зразком. Разом із зображенням варто зберегти розмір вікна, стан даних і причину погодження. Без цього згодом неможливо відрізнити навмисну зміну дизайну від випадкової зміни середовища.

Коли продукт змінюється навмисно, новий базовий стан слід створювати з уже перевіреного результату. Не оновлюйте всі зображення однією командою після випуску. Це швидко, але так само легко можна погодити саме ту помилку, заради якої існує тест. Переглядайте змінені сторінки невеликими групами й залишайте попередній погоджений результат в історії.

  • Огляньте перший знімок повністю перед погодженням.
  • Зберігайте з ним дані про розмір вікна й стан сторінки.
  • Створюйте новий зразок лише з перевіреного результату.
  • Не видаляйте попередній погоджений стан після оновлення.

Поріг має прибирати різницю рендерингу, а не зміни продукту

Поріг визначає, яку дрібну відмінність між зображеннями можна пропустити. Він не відповідає на питання, чи припустима зміна інтерфейсу. Незначна різниця згладжування на краях літер часто не має значення. Зникла картка тарифу, зміщена назва поля або невидима кнопка є проблемою, навіть якщо займають малу частину довгої сторінки.

Починайте зі строгого порівняння у стабільному браузері. Спершу подивіться на кілька помилок і лише потім змінюйте допуск. Якщо різниця зосереджена навколо літер, вирівняйте версії браузера й шрифтів. Якщо постійно змінюється відео чи відгук, стабілізуйте або вузько замаскуйте саме цю ділянку. Великий загальний поріг приховає не лише шум, а й несподівану помилку поруч.

  • Сприймайте частку змінених пікселів як підказку, а не рішення про випуск.
  • Спочатку виправляйте середовище, а не підвищуйте загальний допуск.
  • Для окремого важливого компонента робіть окремий знімок.
  • Окремо показуйте випадок, коли сторінка взагалі не досягла готового стану.

Обирайте поверхню тестування за тим, хто відповідає за результат

Тест Playwright або Cypress природно живе поруч із кодом. Він може підготувати дані, підмінити API і зупинити об'єднання зміни. Це добрий вибір для компонентів та перевірок випуску, якими керують розробники. Selenium доречний, коли вже є великий набір функціональних сценаріїв або браузерна сітка, а знімок є ще одним результатом того самого запуску.

API знімків підходить, коли іншій системі потрібен файл PNG, PDF або повне зображення сторінки, а порівняння і погодження вона виконує сама. RenderLog корисний, коли для сторінки потрібні перевірений базовий стан, повторні запуски, видима різниця, історія і сповіщення для продукту, маркетингу, агенції чи клієнта. Одна команда може застосовувати всі три підходи, якщо не дублює ту саму перевірку без відповідального.

  • Компоненти й блокування змін тримайте в репозиторії.
  • Використовуйте API, якщо потрібен файл, а перегляд виконує ваша система.
  • Спільна поверхня потрібна для запланованих перевірок і кількох команд.
  • Не запускайте той самий повний знімок у всіх інструментах без власника.

До оновлення базового стану визначте причину невдачі

Корисний невдалий запуск відповідає на три питання: що змінилося, чи завершилася сторінка і які докази доступні. Перегляньте базове й поточне зображення та різницю в однаковому масштабі. Потім перевірте стан сторінки, ознаку готовності, журнали браузера й твердження тесту. Порожній знімок після перевищення часу є помилкою запуску. Готова сторінка без картки плану є зміною продукту. Це не одна й та сама червона позначка.

Повторювані причини варто називати. Шум середовища вказує на браузер, шрифти або дані. Неочікувана зміна продукту потребує розслідування. Очікувана зміна потребує погодження. Зламана перевірка потребує нової ознаки готовності або точнішого селектора. Такий поділ не дає команді бездумно оновлювати зображення, доки тестам перестануть довіряти.

  • Помилка запуску: сторінка або знімок не завершилися.
  • Різниця середовища: поточний стан не можна порівнювати зі зразком.
  • Неочікувана зміна продукту: спочатку з'ясуйте причину.
  • Очікувана зміна продукту: погодьте її із записаним поясненням.

Створіть невеликий набір, який команда справді підтримуватиме

Почніть із трьох-п'яти станів, для яких відомий відповідальний: тарифи, успішна реєстрація, підсумок замовлення, важлива сторінка документації та один показовий мобільний стан. Запускайте їх під час випуску або за розкладом, що відповідає частоті змін. Сто безіменних знімків створюють більше шуму, ніж п'ять перевірок, прив'язаних до реальних рішень.

Раз на квартал переглядайте набір. Видаляйте перевірку, якщо на її невдачі ніхто не реагує. Розділяйте сторінку, коли одна нестабільна ділянка заважає бачити важливу стабільну частину. Додавайте новий стан після справжньої помилки або повторюваної ручної перевірки, а не лише тому, що в sitemap з'явилася ще одна адреса. Добре покриття йде за ризиком і відповідальністю, а не за кількістю URL.

  • Дайте кожній перевірці відповідального і зрозумілу причину існування.
  • Додавайте настільний і мобільний стани лише там, де обидва важливі.
  • Пов'язуйте результат із рішенням про випуск, клієнта або робочий процес.
  • Видаляйте перевірки, результати яких уже нічого не змінюють.

Який спосіб візуального тестування відповідає завданню?

Інструменти перетинаються на етапі створення знімка. Важлива різниця полягає в тому, хто керує станом сторінки, де переглядають результат і що має статися після виявленої зміни.

РішенняPlaywright, Cypress або SeleniumAPI знімківRenderLog
ВідповідальнийРозробники й перевірка кодуСистема, яка замовляє файлПродукт, операції, агенція або змішана команда
Керування станомДані, підміни й сценарії в кодіПараметри запиту і логіка клієнтаЗбережені перевірки, сценарії, розклад та API-запуски
ПереглядРезультат CI або запит на зміниСтворюється на боці клієнтаЗразок, поточний результат, різниця та історія запусків
Коли обратиПеревірка має блокувати кодПотрібен лише готовий файлПотрібні повторний перегляд і спільна відповідальність

Мінімальні приклади для трьох поширених наборів інструментів

Ці фрагменти показують лише місце створення знімка, а не готовий виробничий набір. Додайте відтворювані дані, збереження результатів і визначений шлях погодження, перш ніж вважати перший успішний запуск покриттям.

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.

Першоджерела, використані в посібнику

Подробиці API змінюються. Під час реалізації звіряйтеся з офіційною документацією, а цей посібник використовуйте для рішень про відтворюваність, відповідальність і перегляд.

Перейдіть до конкретного робочого процесу

Почніть зі сторінки, яку вже хтось перевіряє вручну

Створіть збережену перевірку для тарифів, реєстрації або клієнтської сторінки, за яку вже відповідає конкретна людина. Погоджуйте перший базовий стан лише після того, як зможете повторити дані, розмір вікна і стан сторінки.

Створити робочий простір RenderLog