- Home »

Запуск end-to-end тестов с Playwright и Docker
Разворачивание end-to-end тестов в продакшене — это то, что рано или поздно приходится делать каждому девопсу. Особенно когда дело касается автоматизации тестирования фронтенда в CI/CD пайплайнах. Playwright в паре с Docker — это мощная комбинация для создания стабильных и изолированных тестовых окружений. В этой статье разберём, как поднять полноценную тестовую среду с нуля, настроить контейнеризацию и избежать классических граблей при работе с браузерной автоматизацией в серверных средах.
Зачем Docker для Playwright-тестов?
Основная проблема при запуске браузерных тестов на серверах — это зависимости. Playwright требует установки браузеров, их зависимостей, правильной настройки окружения. На продакшн-сервере это может конфликтовать с другими процессами или просто не работать из-за отсутствия графического интерфейса.
Docker решает эти проблемы изоляцией:
- Все браузеры и зависимости упакованы в контейнер
- Одинаковое окружение на dev/stage/prod
- Легкое масштабирование тестов
- Отсутствие конфликтов с системными пакетами
Подготовка окружения
Для работы понадобится сервер с Docker. Если у вас ещё нет подходящего сервера, можно взять VPS или выделенный сервер с достаточными ресурсами.
Минимальные требования:
- 2 CPU cores
- 4GB RAM
- 10GB свободного места
- Docker 20.10+
Установка Docker (если ещё не установлен):
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker
Создание базового Dockerfile
Playwright предоставляет готовые Docker-образы с предустановленными браузерами. Создаём структуру проекта:
mkdir playwright-e2e-tests
cd playwright-e2e-tests
mkdir tests
mkdir results
Создаём Dockerfile:
FROM mcr.microsoft.com/playwright:v1.40.0-focal
WORKDIR /app
# Копируем package.json и устанавливаем зависимости
COPY package*.json ./
RUN npm ci
# Копируем тесты
COPY . .
# Устанавливаем браузеры (если нужны дополнительные)
RUN npx playwright install
# Запускаем тесты
CMD ["npx", "playwright", "test"]
Настройка Playwright конфигурации
Создаём package.json с необходимыми зависимостями:
{
"name": "playwright-e2e-docker",
"version": "1.0.0",
"devDependencies": {
"@playwright/test": "^1.40.0"
},
"scripts": {
"test": "playwright test",
"test:headed": "playwright test --headed",
"test:debug": "playwright test --debug"
}
}
Конфигурация playwright.config.js для работы в Docker:
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [
['html', { outputFolder: 'results/html-report' }],
['json', { outputFile: 'results/results.json' }],
['junit', { outputFile: 'results/junit.xml' }]
],
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
video: 'retain-on-failure',
screenshot: 'only-on-failure',
// Важно для Docker - отключаем песочницу
launchOptions: {
args: ['--no-sandbox', '--disable-setuid-sandbox']
}
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
webServer: process.env.CI ? undefined : {
command: 'npm run start',
port: 3000,
},
});
Создание тестового примера
Создаём простой тест в tests/example.spec.js:
const { test, expect } = require('@playwright/test');
test('homepage has title', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveTitle(/My App/);
});
test('navigation works', async ({ page }) => {
await page.goto('/');
await page.click('text=About');
await expect(page).toHaveURL(/.*about/);
});
test('form submission', async ({ page }) => {
await page.goto('/contact');
await page.fill('#name', 'Test User');
await page.fill('#email', 'test@example.com');
await page.click('button[type="submit"]');
await expect(page.locator('.success-message')).toBeVisible();
});
Docker Compose для удобства
Создаём docker-compose.yml для более удобного управления:
version: '3.8'
services:
playwright-tests:
build: .
volumes:
- ./results:/app/results
- ./tests:/app/tests
environment:
- BASE_URL=https://example.com
- CI=true
depends_on:
- app
networks:
- test-network
app:
image: nginx:alpine
ports:
- "3000:80"
volumes:
- ./public:/usr/share/nginx/html
networks:
- test-network
networks:
test-network:
driver: bridge
Запуск тестов
Теперь можно запускать тесты несколькими способами:
# Сборка образа
docker build -t playwright-e2e .
# Запуск тестов
docker run -v $(pwd)/results:/app/results playwright-e2e
# Или через docker-compose
docker-compose up --build
# Запуск в интерактивном режиме для отладки
docker run -it --entrypoint bash playwright-e2e
Практические кейсы и проблемы
Проблема | Решение | Рекомендации |
---|---|---|
Тесты падают с “Browser not found” | Добавить RUN npx playwright install в Dockerfile | Использовать официальные образы с предустановленными браузерами |
Медленная работа в headless режиме | Добавить –no-sandbox в launchOptions | Для Docker всегда отключать песочницу браузера |
Нестабильные тесты | Увеличить timeout, добавить retry | Использовать явные ожидания вместо sleep |
Большой размер образа | Использовать multi-stage builds | Кэшировать node_modules слой |
Оптимизация Docker образа
Для продакшена лучше использовать многоэтапную сборку:
FROM mcr.microsoft.com/playwright:v1.40.0-focal as base
WORKDIR /app
# Установка зависимостей
FROM base as dependencies
COPY package*.json ./
RUN npm ci --only=production
# Финальный образ
FROM base as final
COPY --from=dependencies /app/node_modules ./node_modules
COPY . .
# Создаем пользователя для безопасности
RUN groupadd -r pwuser && useradd -r -g pwuser -G audio,video pwuser \
&& mkdir -p /home/pwuser/Downloads \
&& chown -R pwuser:pwuser /home/pwuser \
&& chown -R pwuser:pwuser /app
USER pwuser
CMD ["npx", "playwright", "test"]
Интеграция с CI/CD
Пример GitHub Actions workflow:
name: E2E Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run E2E tests
run: |
docker build -t playwright-e2e .
docker run -v $(pwd)/results:/app/results playwright-e2e
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results
path: results/
Мониторинг и логирование
Для отслеживания результатов тестов можно настроить отправку метрик:
#!/bin/bash
# test-runner.sh
# Запуск тестов
docker run -v $(pwd)/results:/app/results playwright-e2e
# Парсинг результатов
PASSED=$(jq '.stats.passed' results/results.json)
FAILED=$(jq '.stats.failed' results/results.json)
# Отправка в мониторинг
curl -X POST "http://monitoring:8086/write?db=tests" \
-d "playwright_tests,environment=prod passed=${PASSED},failed=${FAILED}"
# Уведомления в Slack при провале
if [ $FAILED -gt 0 ]; then
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"E2E tests failed: '${FAILED}' tests"}' \
$SLACK_WEBHOOK_URL
fi
Альтернативные решения
Кроме Playwright + Docker существуют другие варианты:
- Selenium Grid — классическое решение, но требует больше настройки
- Cypress — хороший инструмент, но ограничен Chromium-based браузерами
- Puppeteer — только Chrome/Chromium, но очень быстрый
- TestCafe — не требует WebDriver, но менее гибкий
Сравнение производительности (среднее время выполнения 100 тестов):
Инструмент | Время выполнения | Потребление RAM | Поддержка браузеров |
---|---|---|---|
Playwright | ~3 мин | ~500MB | Chrome, Firefox, Safari |
Selenium | ~5 мин | ~800MB | Все основные |
Cypress | ~4 мин | ~400MB | Chrome, Edge |
Puppeteer | ~2 мин | ~300MB | Chrome/Chromium |
Расширенные возможности
Playwright в Docker открывает интересные возможности:
- Параллельное выполнение — запуск нескольких контейнеров одновременно
- Скриншоты и видео — автоматическое сохранение при падении тестов
- Сетевые моки — перехват и подмена API запросов
- Геолокация и мобильная эмуляция — тестирование responsive дизайна
Пример параллельного запуска:
# docker-compose.parallel.yml
version: '3.8'
services:
tests-chrome:
build: .
environment:
- BROWSER=chromium
volumes:
- ./results/chrome:/app/results
tests-firefox:
build: .
environment:
- BROWSER=firefox
volumes:
- ./results/firefox:/app/results
tests-webkit:
build: .
environment:
- BROWSER=webkit
volumes:
- ./results/webkit:/app/results
Интеграция с внешними сервисами
Playwright + Docker хорошо интегрируется с внешними сервисами:
// tests/api-integration.spec.js
const { test, expect } = require('@playwright/test');
test.describe('API Integration Tests', () => {
test('should work with external API', async ({ page, request }) => {
// Мокаем API ответ
await page.route('**/api/users', route => {
route.fulfill({
status: 200,
body: JSON.stringify([
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Smith' }
])
});
});
await page.goto('/users');
await expect(page.locator('.user-list')).toContainText('John Doe');
});
test('should handle API errors gracefully', async ({ page }) => {
await page.route('**/api/users', route => {
route.fulfill({ status: 500 });
});
await page.goto('/users');
await expect(page.locator('.error-message')).toBeVisible();
});
});
Автоматизация развёртывания
Для автоматизации можно создать bash-скрипт:
#!/bin/bash
# deploy-tests.sh
set -e
ENVIRONMENT=${1:-staging}
TESTS_DIR="/opt/playwright-tests"
RESULTS_DIR="/var/log/playwright-results"
echo "Deploying E2E tests for $ENVIRONMENT environment"
# Подготовка директорий
mkdir -p $RESULTS_DIR
cd $TESTS_DIR
# Получение последних изменений
git pull origin main
# Сборка образа
docker build -t playwright-e2e:$ENVIRONMENT .
# Запуск тестов
docker run \
--name playwright-tests-$ENVIRONMENT \
--rm \
-v $RESULTS_DIR:/app/results \
-e BASE_URL=$BASE_URL \
-e ENVIRONMENT=$ENVIRONMENT \
playwright-e2e:$ENVIRONMENT
echo "Tests completed. Results available in $RESULTS_DIR"
# Очистка старых результатов (старше 30 дней)
find $RESULTS_DIR -name "*.json" -mtime +30 -delete
Заключение и рекомендации
Playwright + Docker — это мощная комбинация для создания надёжных e2e тестов. Основные преимущества:
- Изоляция — тесты не зависят от окружения сервера
- Воспроизводимость — одинаковое поведение везде
- Масштабируемость — легко добавить больше тест-раннеров
- Безопасность — браузеры изолированы в контейнере
Когда использовать:
- Для CI/CD пайплайнов
- При необходимости тестирования в разных браузерах
- Для регрессионного тестирования
- При работе с микросервисной архитектурой
Где не стоит использовать:
- Для простых smoke-тестов (избыточно)
- При критичности скорости выполнения
- Для тестирования native мобильных приложений
Начните с простой конфигурации и постепенно добавляйте сложность. Используйте официальные образы Playwright — в них уже решено большинство проблем с зависимостями. И не забывайте про мониторинг — без него сложно понять, когда тесты начинают «врать».
Для получения дополнительной информации обращайтесь к официальной документации: Playwright Docker Guide и Docker Compose Documentation.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.