lenec ru

← все посты

Playwright vs Cypress: что брать в 2026

14K

End-to-end тесты в 2026 году окончательно сменили парадигму. Cypress, который ещё пять лет назад был дефолтом, уступил место Playwright почти во всех новых проектах. Я держу два рабочих стека: один на Playwright (новый продукт), один на Cypress (legacy, уже два года не мигрируем). Сравню по реальным сценариям и расскажу, в чём ключевые различия.

Кратко про каждый

Cypress — фреймворк для UI-тестов, написанный на JavaScript и работающий внутри окна браузера. Тестовая логика и тестируемое приложение живут в одном процессе.

Playwright — фреймворк от Microsoft, который управляет браузером извне через CDP. Поддерживает Chromium, Firefox, WebKit. Один API на всех.

Установка и первый тест

Cypress:

pnpm add -D cypress
pnpm cypress open

Playwright:

pnpm dlx create-playwright@latest

Утилита создаст конфиг, поставит браузеры, сгенерирует пример теста.

Базовый тест в Cypress:

describe('login', () => {
  it('opens', () => {
    cy.visit('/login');
    cy.get('input[name=email]').type('alice@example.com');
    cy.get('input[name=password]').type('secret');
    cy.contains('Войти').click();
    cy.url().should('include', '/dashboard');
  });
});

Базовый тест в Playwright:

import { test, expect } from '@playwright/test';

test('login', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Email').fill('alice@example.com');
  await page.getByLabel('Password').fill('secret');
  await page.getByRole('button', { name: 'Войти' }).click();
  await expect(page).toHaveURL(/\/dashboard/);
});

API Playwright немного многословнее, но локаторы — по семантике (role, label, text), что попадает ближе к accessibility и не ломается при смене разметки.

Скорость

Это первая большая разница. Playwright параллелит тесты по worker'ам из коробки. На моём проекте с 320 тестами:

  • Cypress, sequential: ~12 минут.
  • Cypress, parallel (4 машины через Cloud): ~3.5 минуты.
  • Playwright, parallel (1 машина, 4 worker'а): ~2.8 минуты.
  • Playwright, parallel (4 машины): ~50 секунд.

Параллельность Playwright бесплатная и встроенная. У Cypress параллелизм требует Cypress Cloud (платная подписка) или собственной инфраструктуры с настройкой шардирования.

Изоляция и контекст

Cypress запускает все тесты в одном браузере, переключаясь между origin'ами. Это создаёт интересные ограничения: например, до недавнего времени нельзя было ходить на разные домены в одном тесте.

Playwright создаёт отдельный BrowserContext на каждый тест. Это как «новое инкогнито-окно»: куки, localStorage, кеш — всё чистое. Тесты изолированы по-настоящему.

// playwright: каждый тест получает свой context
test('test 1', async ({ page }) => {
  // изолированный page
});

test('test 2', async ({ page }) => {
  // другой изолированный page
});

Эта изоляция означает, что тесты можно безбоязненно гонять параллельно. В Cypress параллельные тесты в одном браузере давали побочные эффекты, и их обходили через cy.session.

Кросс-браузерное тестирование

Playwright из коробки поддерживает Chromium, Firefox, WebKit. Один тест прогоняется на всех трёх:

// playwright.config.ts
export default defineConfig({
  projects: [
    { name: 'chromium', use: { browserName: 'chromium' } },
    { name: 'firefox', use: { browserName: 'firefox' } },
    { name: 'webkit', use: { browserName: 'webkit' } },
  ],
});

На CI — три прогона параллельно. Это закрывает 99% реальной аудитории.

Cypress долгое время поддерживал только Chromium-семейство. В 2024 завезли поддержку Firefox и Edge, но не WebKit. Если ваш продукт должен работать на Safari — Cypress не закрывает эту проблему естественно.

Network mocking

В обоих можно перехватывать запросы. Cypress:

cy.intercept('GET', '/api/users', { fixture: 'users.json' });

Playwright:

await page.route('**/api/users', (route) =>
  route.fulfill({ json: { users: [...] } }),
);

Playwright API чуть более мощный: можно модифицировать запросы (заголовки, тело), задерживать ответы, создавать ошибки. Cypress — проще для типичных кейсов, Playwright — гибче для нестандартных.

Дебагинг

Cypress имеет встроенный браузерный UI с time-travel: видишь снимки приложения после каждой команды. Это сильная сторона Cypress — для UI-тестировщика без программистского бэкграунда это удобнее всего.

Playwright имеет похожий инструмент — Playwright Inspector + Trace Viewer. Trace Viewer записывает полный прогон теста с DOM-снимками, network logs, console output. Открывается отдельным процессом, читается через Чейн чем CLI:

pnpm playwright show-trace trace.zip

Информации больше, чем в Cypress. Но кривая обучения чуть круче.

Codegen

Обе системы умеют генерировать код по действиям пользователя. Playwright:

pnpm playwright codegen https://example.com

Открывается браузер, ты кликаешь, генератор пишет код. На выходе — готовый тест. Для UI-тестировщиков и ручных QA это снижает порог входа.

Cypress Studio — похожая фича, но я её использовала меньше, и встречала баги при работе со сложными формами.

Component testing

Оба фреймворка умеют тестировать React/Vue компоненты в браузере без целого приложения.

Cypress Component Testing считается зрелым.

Playwright Component Testing в 2026 году ещё в experimental, и я предпочитаю для component-тестов брать Vitest browser mode или Cypress.

Стоимость и инфраструктура

Playwright — бесплатный, открытый, с MS поддержкой. CI настраивается через GitHub Actions runner или собственное железо.

Cypress — open-source ядро, но Cypress Cloud (с параллелизацией, аналитикой, dashboard) — платный. Для небольшой команды бесплатного хватает; для большой — счёт ощутимый.

Что я выбираю в 2026

  • Новый проект — Playwright, без вариантов. Бесплатная параллелизация, кросс-браузерность, отличный API.
  • Старый Cypress-проект — оставить, мигрировать только если есть боль (медленные тесты, нестабильность).
  • Component testing — Vitest browser mode или Cypress Component Testing.
  • Команда из ручных QA без программистского опыта — Cypress, у него UI всё ещё дружелюбнее.

Грабли

В Playwright: типизированные локаторы (getByRole, getByLabel) меняют, как ты пишешь тесты. На первом проекте я по привычке писала page.locator('.btn-primary') — работало, но отчёты выходили хуже, и тесты ломались на смене класса. Перевела на семантические локаторы — стало стабильнее.

В Cypress: cy.session — спасение для аутентификации между тестами, но требует понимания. Без него каждый тест проходит логин заново, что дорого.

Миграция Cypress → Playwright

Я делала такую миграцию на одном проекте. Шаги:

  1. Поставить Playwright рядом с Cypress.
  2. Переписать вспомогательные хелперы (login, seed, ожидания) под Playwright.
  3. Мигрировать самые часто падающие тесты (обычно это 10-20% от общего числа).
  4. После каждого пакета тестов — удалить из Cypress.
  5. Финальный коммит — снести Cypress.

Заняло три недели на 240 тестов. Это много, но и качество тестов после миграции выросло — переписывая, я их улучшала.

Что копать дальше

Если ты только подбираешь стек — поставь Playwright и проведи через него хотя бы один тест. Кривая обучения 1-2 дня. Если у тебя нагретый Cypress, не торопись с миграцией: ROI миграции виден только при определённых масштабах. Иногда лучше потратить эти ресурсы на стабильность тестов в существующем стеке.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.