QA Interview Hub · База знань · Тести
Cypress
Cypress проти Playwright
порівняння й міграція
У чому ключові відмінності Cypress і Playwright?
| Cypress | Playwright |
| Де живе тест | Усередині браузера | Ззовні, через протокол браузера |
| Асинхронність | Черга команд, без await | Promise, async/await |
| Очікування | Retry queries і should, 4 с | Auto-waiting дій, expect 5 с |
| Ізоляція | Очищення стану в одному браузері | Новий BrowserContext на тест |
| Вкладки й домени | Одна вкладка, cy.origin | Будь-яка кількість |
| Паралельність | Між машинами, Cloud або плагін | Воркери вбудовано, шардинг |
| Браузери | Chromium, Firefox, WebKit експериментально | Chromium, Firefox, WebKit |
| Мережа | cy.intercept через проксі | page.route через протокол |
| Дебаг | Time-travel у Test Runner | Trace Viewer, UI mode |
| Мови | JavaScript, TypeScript | JS/TS, Python, Java, .NET |
На співбесіді: Корінна відмінність: Cypress працює всередині браузера, а Playwright керує ним ззовні. З цього випливає все інше. Cypress має чергу команд замість async/await, одну вкладку, паралелізацію лише між машинами і перехоплення мережі через проксі. Playwright має звичайні проміси, кілька вкладок і доменів, ізольовані контексти, вбудовані воркери і підтримує кілька мов. Зате в Cypress дуже зручний дебаг з time-travel.
Коли ти обереш Cypress, а не Playwright?
Cypress доречний, коли застосунок односторінковий, з одним доменом і однією вкладкою, а тести пишуть переважно фронтенд-розробники, яким важливі time-travel і компонентне тестування в тому самому інструменті.
Вирішальний фактор частіше — наявний стек: якщо на проєкті вже є великий набір на Cypress і люди, які його знають, переписувати немає сенсу. Для нового проєкту без такої спадщини сьогодні дефолтом зазвичай є Playwright.
На співбесіді: Я обрав би Cypress, якщо застосунок — односторінковий, на одному домені, а тести пишуть разом з фронтенд-розробниками, яким зручні time-travel і компонентні тести. Ще важливіше — що вже є на проєкті: якщо там великий набір на Cypress і команда його знає, переписувати не варто. А для нового проєкту з нуля я б узяв Playwright.
Як би ти мігрував проєкт з Cypress на Playwright?
- Не переписувати все одразу. Нові тести пишуться на Playwright, старі працюють паралельно в CI і переносяться поступово, починаючи з найкритичніших і найбільш флакі.
- Перенести архітектуру, а не синтаксис. Page Object переходить майже напряму, але методи стають
async. Кастомні команди перетворюються на фікстури або хелпери. cy.session замінює storageState із setup-проєктом.
- Мережа:
cy.intercept з alias перетворюється на page.route або page.waitForResponse.
- Ризики: тимчасово два стеки в CI, навчання команди, неявні залежності між Cypress-тестами, які стануть помітні в паралельному запуску.
- Критерій успіху: менше флакі, швидший прогін завдяки воркерам, покриття не просіло.
// Cypress
cy.intercept('GET', '/api/stats').as('stats');
cy.get('[data-cy=period]').select('30d');
cy.wait('@stats');
cy.get('[data-cy=chart]').should('be.visible');
// Playwright
const stats = page.waitForResponse('**/api/stats');
await page.getByTestId('period').selectOption('30d');
await stats;
await expect(page.getByTestId('chart')).toBeVisible();
На співбесіді: Я б не переписував усе одразу. Нові тести пишуться на Playwright, старі живуть поруч у CI і переносяться поступово, починаючи з критичних і найбільш нестабільних. Переношу архітектуру, а не рядки: Page Object майже напряму, але з async, кастомні команди стають фікстурами, cy.session — storageState, intercept з alias — waitForResponse. Головні ризики — два стеки одночасно і приховані залежності між тестами, які вилізуть при паралельному запуску. Успіх міряю стабільністю, швидкістю прогону і тим, що покриття не просіло.