Visual regression testing

Visual regression testing является важным аспектом автоматизированного тестирования, позволяющим убедиться в корректности визуального отображения веб-приложений после изменений в коде. Вместо того чтобы проверять только функциональность элементов, визуальное регрессионное тестирование фокусируется на изменениях в UI, которые могут быть незаметны при ручном тестировании. В этой главе рассматриваются основные подходы к реализации визуального регрессионного тестирования с использованием Puppeteer.

Важность визуального регрессионного тестирования

Каждый раз, когда в проекте происходят изменения, есть вероятность того, что они повлияют на внешний вид страницы. Это может привести к неожиданным багам в интерфейсе, которые сложно отследить с помощью стандартных юнит-тестов. Визуальное регрессионное тестирование помогает быстро выявить такие изменения, сравнивая текущий снимок экрана с эталонным изображением.

Как работает Puppeteer в контексте визуального тестирования

Puppeteer — это библиотека для Node.js, которая предоставляет API для управления браузером Chrome или Chromium через протокол DevTools. Она позволяет делать скриншоты страниц, взаимодействовать с элементами на веб-странице и даже записывать видео сеансов. Для визуального регрессионного тестирования Puppeteer помогает захватывать изображения в разных состояниях страницы и сравнивать их с эталонными снимками.

Основные шаги в визуальном тестировании с Puppeteer

  1. Настройка окружения: Для начала работы с Puppeteer необходимо установить его через npm:

    npm install puppeteer
  2. Запуск браузера: Для создания снимков экрана необходимо запустить экземпляр браузера и открыть нужную страницу. Это можно сделать с помощью следующего кода:

    const puppeteer = require(&
    
    (async () => {
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      await page.goto('https://example.com');
    })();
  3. Снятие снимков экрана: Для захвата скриншота страницы используется метод screenshot(), который сохраняет изображение в файл:

    await page.screenshot({ path: 'example.png' });
  4. Сравнение снимков: На основе снятых скриншотов необходимо сравнить их с эталонными изображениями, чтобы выявить различия. Для этого можно использовать специальные библиотеки для визуального сравнения, такие как pixelmatch или looks-same.

    Пример с использованием pixelmatch:

    npm install pixelmatch

    Далее сравниваем два изображения:

    const fs = require('fs');
    const pixelmatch = require('pixelmatch');
    const PNG = require('pngjs').PNG;
    
    const img1 = PNG.sync.read(fs.readFileSync('baseline.png'));
    const img2 = PNG.sync.read(fs.readFileSync('example.png'));
    const { width, height } = img1;
    
    const diff = new PNG({ width, height });
    const numDiffPixels = pixelmatch(img1.data, img2.data, diff.data, width, height, { threshold: 0.1 });
    
    fs.writeFileSync('diff.png', PNG.sync.write(diff));
    console.log(`Number of different pixels: ${numDiffPixels}`);

    В этом примере используется библиотека pixelmatch, которая сравнивает два изображения пиксель за пиксель. Если есть различия, то они будут сохранены в новый файл diff.png. Это изображение покажет, какие области экрана изменились.

Техники улучшения точности визуального тестирования

  1. Учет различных разрешений экрана: Визуальное регрессионное тестирование должно учитывать возможные изменения, вызванные различными размерами экрана и разрешениями. Чтобы улучшить точность, можно тестировать на нескольких устройствах и разрешениях, используя Puppeteer:

    await page.setViewport({ width: 1280, height: 800 });

    Для тестирования на разных устройствах можно задать такие настройки как для мобильных, так и для десктопных версий.

  2. Влияние динамических элементов: Некоторые элементы на странице, такие как изображения, шрифты или анимации, могут изменяться между тестами. Чтобы уменьшить влияние таких факторов, можно скрыть динамические элементы или заморозить анимации перед снятием скриншота:

    await page.addStyleTag({ content: '* { animation: none !important; }' });
  3. Отслеживание изменений в UI: В некоторых случаях изменения в интерфейсе могут быть вызваны не только кодом, но и внешними факторами, такими как различия в шрифтах, цветах или других стилях. Чтобы уменьшить влияние таких факторов, важно использовать несколько эталонных снимков с разных точек времени, обеспечивая стабильность визуальных тестов.

Сравнение изображений и выводы

После выполнения тестов и получения различий между эталонным и текущим изображением важно правильно интерпретировать результат:

  • Небольшие различия: Если различия минимальны и не влияют на пользовательский опыт, их можно проигнорировать или откорректировать эталонные изображения.
  • Критические ошибки: Если визуальные изменения критичны и могут повлиять на функциональность страницы, нужно либо исправить их в коде, либо обновить эталонный снимок, если изменения были предусмотрены.

Интеграция с CI/CD

Визуальные регрессионные тесты можно интегрировать с процессами непрерывной интеграции и доставки (CI/CD). Это позволяет автоматически запускать тесты при каждом изменении в коде, обеспечивая своевременное выявление визуальных дефектов. Например, с использованием GitHub Actions или Jenkins можно настроить pipeline для выполнения Puppeteer тестов.

Пример интеграции с GitHub Actions:

name: Visual Regression Test

on:
  push:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14'
      - run: npm install
      - run: npm test

Заключение

Использование Puppeteer для визуального регрессионного тестирования позволяет эффективно и быстро проверять внешний вид веб-страниц, минимизируя риск появления визуальных багов в продакшн-версии. Важно правильно настроить тесты и учитывать различные аспекты интерфейса, такие как разрешение экрана и динамические элементы. Интеграция с CI/CD улучшает процесс разработки, ускоряя выявление и устранение дефектов на ранних этапах.