Что такое headless-тестирование?

Headless-браузер — это веб-браузер, работающий без графического интерфейса. Он имеет полный движок — HTML-парсер, CSS-движок, JS-среду, сетевой стек — но не рендерит пиксели на экран. Тесты в headless-режиме выполняют все те же операции, что и в обычном браузере, но без затрат на отрисовку.

Headless-тестирование стало мейнстримом после введения Chrome headless mode в 2017 году. Сегодня все основные браузеры поддерживают headless.

Зачем headless-режим?

Скорость

Без рендеринга пикселей браузеры работают быстрее. Типичное ускорение 20-40%.

CI/CD-окружения

Большинство CI/CD-серверов не имеют графического дисплея. Headless позволяет запускать тесты без виртуального дисплея.

Экономия ресурсов

Headless-браузеры используют меньше памяти и CPU.

Настройка headless-режима

Playwright

const browser = await chromium.launch(); // Headless по умолчанию
const browser = await chromium.launch({ headless: false }); // Headed для отладки

Cypress

npx cypress run          # Headless по умолчанию
npx cypress run --headed # Принудительно headed
npx cypress open         # Интерактивный/headed

Selenium

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
options.addArguments("--window-size=1920,1080");
WebDriver driver = new ChromeDriver(options);

Когда headed, когда headless

СценарийРежимПочему
CI/CD-пайплайнHeadlessНет дисплея, быстрее
Локальная разработкаHeadedВидно работу тестов, отладка
Визуальная регрессияHeaded рекомендуетсяРендеринг должен совпадать с продакшеном
Отладка паденияHeadedНаблюдение за пошаговым выполнением

Ограничения и подводные камни

Различия рендеринга

Headless и headed режимы могут давать разный визуальный результат: рендеринг шрифтов, CSS-анимации, обработка viewport.

Расширения браузера

Headless обычно не загружает расширения.

Системные диалоги

Диалоги скачивания и печати работают иначе в headless.

// Playwright — обработка скачиваний в headless
const [download] = await Promise.all([
  page.waitForEvent('download'),
  page.click('#download-button')
]);

Сложность отладки

Способы решения: скриншоты при падении, запись видео, trace viewer Playwright, переключение на headed для воспроизведения.

use: {
  trace: 'on-first-retry',
  screenshot: 'only-on-failure',
  video: 'retain-on-failure',
}

Docker и headless-тестирование

FROM mcr.microsoft.com/playwright:v1.40.0-focal
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npx", "playwright", "test"]

Упражнения

Упражнение 1: Настройка headless

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

Упражнение 2: CI/CD-пайплайн

Создайте GitHub Actions workflow с headless, скриншотами и видео при падении.

Упражнение 3: Отладка headless-падений

Создайте тест, проходящий в headed но падающий в headless, диагностируйте через trace viewer, исправьте.