Чому я перейшов із Cypress на Playwright

Усі статті, обговорення, новини про тестування — в одному місці. Підписуйтеся на DOU | QA!

Привіт, мене звати Олександр Гуменюк. Я працюю Front-end розробником у стартапі AlphaNovel від венчур-білдера SKELAR. Ми створюємо маркетплейс романтичних новел і коміксів для читачів і письменників з усього світу.

Сьогодні я розповім, чому наша команда вирішила переписати всі E2E-тести з Cypress на Playwright та наведу конкретні приклади переваг Playwright, які ми для себе відкрили. Зауважте, хоча Playwright підтримує й інші мови програмування (за що йому ще один плюсик), приклади коду будуть на TypeScript.

Водночас усі переваги Playwright зберігаються, незалежно від мови програмування.

Коротко про Cypress i Playwright

Cypress — це open-source JavaScript-фреймворк для написання тестів для вебзастосунків, випущений у 2017 році. Особливість Cypress — це те, що його команди запускаються всередині браузера, а не комунікують з браузером ззовні, як це роблять інші фреймворки.

Cypress може використовуватись для E2E-тестування, API-тестування, а також для Unit/Component-тестування. Окрім фреймворку, Cypress також пропонує своє комерційне рішення для запису, аналізу та паралелізації тестів у CI/CD — вебзастосунок Cypress Cloud.

Playwright test — це open-source фреймворк для E2E-тестування вебзастосунків, випущений Microsoft у 2020 році. Основна ціль Playwright — це надати одне API для різних браузерів, платформ, девайсів та мов програмування. Для комунікації з браузерами Playwright використовує Chrome DevTools Protocol, або схожі власні протоколи (для WebKit i Firefox браузерів).

Історія використання

Для нас усе почалось з потреби автоматизації тестування вебзастосунків. Ресурсу Automation QA не вистачало, щоб писати E2E-тести для вебу, тому, посінкавшись з командою, ми домовилися взяти цю задачу на себе, водночас тісно взаємодіючи з QA.

Коли справа дійшла до вибору інструменту, на той час очевидним фаворитом серед JavaScript-based технологій був Cypress. За даними npm trends, станом на липень 2023 Cypress мав п’ять мільйонів завантажень на тиждень проти 1,4 мільйонів у Playwright. Хоча, як можна помітити на графі, Playwright почав активно набирати популярність останні шість місяців.

Після невеликого дослідженя було обрано Cypress. За декілька місяців ми написали близько 90 E2E-тестів, які покривали основний функціонал вебзастосунку. Проте з часом та числом тестів, що збільшувалося, ми зіштовхнулися з ускладненням структури фреймворку для тестування і все більшою кількістю еджкейсів, з якими Cypress не міг впоратись.

Також розглядали питання переходу на платний план Cypress Cloud; безкоштовних 500 тестів на місяць, звичайно, не вистачало.

Однак перед тим, як остаточно комітитись до Cypress, ми вирішили оцінити альтернативи. Окрім Cypress з популярних JavaScript-інструментів для E2E-тестування були: Playwright, Puppeteer, WebdriverIO та NightWatch.

Ми вирішили спробувати Playwright, написавши декілька автотестів, і результат перевершив наші очікування. Playwright надав нам кращий developer experience, менше обмежень та логічно структурований фреймворк. Залишивши Playwright, за місяць нам вдалось переписати всі наявні E2E-тест на новому інструменті.

Далі я детально розповім про ключові переваги Playwright порівняно з Cypress, які ми виявили для себе, використовуючи обидва інструменти.

1. Підтримка браузерів та девайсів

Playwright має ширшу підтримку браузерів: він може запускати тести на браузерах, які використовують рушії Chromium, Firefox i WebKit. Cypress підтримує лише Chromium і Firefox.

До того ж, Playwright підтримує зручну симуляцію мобільних девайсів з-під коробки. Ця функція не обмежена зміною розміру екрану девайсу, зокрема автоматичною модифікацією таких параметрів, як userAgent, deviceScaleFactor, hasTouch та іншими, що дозволяє більш точно імітувати роботу на реальних пристроях.

Playwright надає приблизно 100 пресетів для різних девайсів та браузерів, які можна використати, вказавши їх у файл конфігурації.

Крім того, Playwright автоматично встановлює флаг isMobile залежно від обраного пресета, полегшуючи налаштування тестів для мобільних пристроїв.

Cypress обмежує вибір браузера для тестування, підтримуючи тільки Chromium i Firefox браузери, і не надає вбудованих пресетів. Також Cypress не надає зручного API для встановлення флагу isMobile у своїх тестах. Внаслідок цього доводиться реалізовувати цей функціонал самостійно через кастомні змінні середовища та налаштування своїх параметрів девайсу.

2. Швидкість

Відповідно до результатів бенчмарку, опублікованими на ChecklyHQ, швидкість Playwright перевищує Cypress більш ніж у три рази. Крім того, Playwright підтримує повну паралельність під час запуску тестів. Це означає, що на одній машині (на CI чи локально) можна одночасно виконувати декілька тестів в різних процесах (worker process).

Cypress, з іншого боку, підтримує тільки паралельність на різних машинах, дозволяючи виконувати лише один тест за раз на одному пристрої.

Для порівняння швидкості можемо використати тест-кейс, який перевіряє навігацію в хедері вебсайту. Реалізація тесту на Cypress:

Реалізація тесту на Playwright:

Швидкість виконання тесту з Cypress:

Швидкість виконання тесту з Playwright (пише, що два тести, тому що перший — це сетап):

Як і очікувалось, Playwright виконав тест майже втричі швидше!

3. Підтримка декількох вікон

Як зазначено на офіційному вебсайті з документацією, через свою архітектуру Cypress ніколи не зможе підтримувати декілька одночасно відкритих браузерів, вікон або вкладок. Playwright не має таких обмежень та без проблем навігує між вкладками, поп-апами та іншими вікнами.

Це дає можливість тестувати складні сценарії, як-от авторизація через сторонні сервіси, як Facebook, Google або Apple, які часто використовують поп-ап вікна для вводу облікових даних.

4. Читабельність коду

Cypress ламає сталі уявлення про асинхронний код у JavaScript та надає свою власну реалізацію асинхронності. Команди Cypress не виконуються відразу, вони записуються в чергу для виконання пізніше. Тому обʼєкти та результати виконання не повертаються, а передаються між командами.

Це означає, що значення не можуть бути безпосередньо збережені в стандартні JavaScript-змінні. Замість цього можна або використовувати синтаксис, схожий на promise через .then, або зберігати результат у так званих aliases, які можна буде пізніше дістати через cy.get.

Такий синтаксис додає більше вкладеностей у код та робить тести менш читабельним, особливо коли потрібно працювати з декількомами alias одночасно. Наприклад:

Playwright повністю підтримує вже знайомий нам синтаксис async / await. Це дозволяє зберігати результати виконання методів у звичайні змінні, значно спрощуючи структуру коду та покращуючи його читабельність тестів. Перепишемо цей тест на Playwright:

5. Типізація

Хоча Cypress і підтримує Typescript, його підхід до асинхронності та використанню aliases дає багато можливостей «вистрілити собі в ногу» типами. Коли ми дістаємо значення alias через cy.get, TypeScript не знає (і не може знати) тип цього значення.

Усе, що ми можемо зробити, це накинути цей тип через Generics до методу cy.get. Водночас цей тип може взагалі не відповідати дійсності, але про це ми дізнаємось тільки в рантаймі. Наприклад:

Тут ми беремо текст з елементу та записуємо його в alias text. Після цього дістаємо це значення та приписуємо йому хибний тип. TypeScript не видає нам помилку, але під час запуску тестів у cy.contains передасться undefined, не те, що ми хочемо.

У тестах Playwright немає таких проблем, оскільки підтримується синтаксис async / await та звичайні змінні, який TypeScript може розуміти. Це надає більш безпечну роботу з типами, знижуючи ризик несподіваних помилок у рантаймі. Переписавши минулий тест, використовуючи Playwright, отримаємо помилку TypeScript:

6. Додаткові інструменти

Окрім звичайного UI-режиму, який є і в Cypress, Playwright дає можливість запускати тести у режимі trace-on і debug.

У режимі trace-on Playwright збирає та зберігає детальну інформацію про виконання тестів: виклики команд та час їхнього виконання, скриншоти/снепшоти, власні логи Playwright та користувацькі консоль-логи, помилки, HTTP-запити та багато іншого.

Після завершення тесту буде відкрито звіт, в якому цю інформацію можна буде переглянути. Також цей звіт можна надіслати іншими у вигляді архіву.

У нашому випадку цей режим знадобився, щоб переглядати результати запуск тестів в CI/CD або розбиратись, чому вони провалились.

Режим debug дозволяє запустити тести в режимі відлагодження. Це дає можливість призупиняти тест або виконувати дії крок за кроком. У такому режимі зручно аналізувати стан системи в реальному часі під час виконання тесту.

Playwright також пропонує потужний codegen-інструмент, за допомогою якого можна згенерувати робочий тест, не написавши жодного рядка коду.

Ми просто відтворюємо дії користувача (клієкамо на кнопки, заповнюємо поля) у тестовому середовищі, а Playwright самостійно визначає необхідні локатори (вираз для ідентифікації елементів на сторінці) та автоматично генерує відповідний код.

7. Ціна

Якщо вам потрібно інтегрувати Cypress E2E-тести в CI/CD pipeline і/або реалізувати їхній паралельний запуск, ви маєте використовувати Cypress Cloud — комерційне рішення від Cypress, вебзастосунок для зберігання і аналізу тест-ранів.

Однак, як я вже згадував вище, безкоштовними є тільки 500 тест-кейсів в місяць; за все, що перевищує цей ліміт, доведеться платити. Платні підписки Cypress стартують з $67 у місяць.

З іншого боку, Playwright виступає як повністю безкоштовна, самодостатня альтернатива. Він дозволяє налаштувати CI/CD з паралельним виконання тестів без сторонніх сервіс та може генерувати HTML-звіти з результатами тест-ранів.

8. Обмеження Cypress

Один з моїх улюблених прикладів для порівняння Cypress i Playwright — це реалізація функції для зміни параметра prefers-color-scheme. Реалізація в Cypress:

Реалізація в Playwright:

Це хороший приклад того, що в Playwright прості речі робляться просто.

До списку проблемних кейсів Cypress ще можна додати його обмежену підтримку iframes і cross-origin тестування (перехід на сторінку з іншим доменом). Cypress не дозволяє обирати елементи всередині iframe напряму, тому потрібно використовувати обхідні шляхи, наприклад:

Щоб переходити між різними доменами потрібно використовувати команду cy.origin або вимкнути chromeWebSecurity в конфігурації Cypress.

Ще одне обмеження Cypress: не весь потрібний для нас функціонал підтримується з-під коробки. Для таких методів, як hover i tab потрібно встановлювати окремий пакет (cypress-real-events). Також для візуального тестування (порівняння скриншотів) потрібен окремий плагін.

Playwright, своєю чергою, підтримує весь потрібний функціонал, зокрема вищезгаданий, без сторонніх пакетів.

Висновок

Після використання обидох технологій у нашому кейсі Playwright показав себе як більш зручний, швидкий і досконалий інструмент, який можна легко адаптувати та масштабувати під свій лад. Його можна використовувати, як all-in-one пакет для E2E-тестування, без сторонніх плагінів або застосунків.

Також великою перевагою Playwright є широка підтримка браузерів, платформ, девайсів та різних мов програмування. Натомість рішення і обмеження Cypress не відповідали потребам нашої команди.

Сподіваюсь, мій досвід буде для вас корисним і краще допоможе у виборі правильної технології. Поділіться власним досвідом використання цих технологій у коментарях!

👍ПодобаєтьсяСподобалось56
До обраногоВ обраному35
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Дякую за статтю, читати було приємно, але хотілося б зробити декілька доповнень по статті та додати дещо від себе.
Отже, щодо статті, хотілось би додати наступне:
1. Підтримка браузерів та девайсів: тут все по ділу окрім інфи про пресети, тому що пресети в Cypress є, ось лінк на статтю з прикладами: docs.cypress.io/api/commands/viewport
2. Швидкість: також правда. Хотілось би захистити Cypress, сказавши, що в гонці після сетапу він би переміг, бо він сидить напряму в браузері, а PW використовує CDP. Але це, звичайно, ні на що не впливає, бо сетап в Cypress реально довгий
3. Підтримка декількох вікон: раніше команда Cypress аргументувала це тим, що це суперечить їх ідеям. Сьогодні ж вони потрохи викатують Puppeteer плагін для цієї мети: github.com/...​ree/develop/npm/puppeteer
4. Читабельність коду: субʼєктивно, але так, більшості людей код Cypress буде здаватись менш читабельним, особливо, якщо писати його так, як на прикладах. У нас в тестах, наприклад, вкладеності використовуються досить рідко. Aliases можна діставати також з глобального контексту Mocha, але для цього потрібно відмовитись від arrow синтаксису функцій, та і взагалі це може заплутати
5. Типізація: тут правда, яким би експертом в TS ви не були, прикрутити типи до команд досить важко, без дженеріків нікуди
6. Додаткові інструменти: в нових версіях Cypress також є трейс вʼювер (docs.cypress.io/guides/cloud/test-replay) (але він схований в їх платний Клауд, тому для звичайних користувачів, виходить, його немає). Дебаг режим є, як `cy.pause` так і `cy.debug`, але в PW це реалізовано краще
Codegen в Cypress є. Я жодного разу його не використовував, тому нічого сказати не можу, але він там є і досить давно: docs.cypress.io/...​references/cypress-studio
7. Ціна: тут правда лише частково. Для інтеграції тестів в CI/CD пайплайн не обовʼязково платити за Cypress Cloud і взагалі використовувати його. Достатньо просто використати їх офіційний action (це для GH Actions) і ранити тести на своїй інфраструктурі
Щодо парлелізації, то так і є. Більш того, Cypress нещодавно заблокували декілька альтернатив, одна все ще є (github.com/bahmutov/cypress-split), але це вже не з коробки. Плюс PW підтримує шардінг (але лише для Ноди, наскільки мені відомо), а в Cypress про таке ніколи й не чули)
8. Обмеження Cypress:
— В PW тут однозначно підхід легше, тому що він використовує CDP напряму, але тут є дзеркальні мінуси, які я описав в пункті 2 плюсів Cypress
— Про iframes. Так, для роботи з cross-origin фреймами доведеться вимикати веб секʼюріті. В іншому, з часів, коли Cypress оновив логіку квірінга елементів, проблем з ними стало набагато менше. Але в PW це зроблено краще, без питань
— Для хаверінгу так, порібно використовувати 3-rd party лібу (яка на практиці просто робить те ж саме, що робить PW і що неможливо зробити з контексту користувача в браузері). І проблема тут більше в тому, що різні додатки імплементують поведінку на хавер по-різному, часто без використання нативних ’mouseover’/’mouseenter’ подій. PW ж просто форсить хавер стейт через дев тулзи, що, насправді, не є дуже реалістичною поведінкою юзера

Це по пунктам, але ще хотілося б додати наступне:
1. Cypress має набагато більше можливостей в плані тестування в контексті assertions. Їх з коробки більше й вони різноманітніші, а також в колбеці `should` можна легко крутити елемент як завгодно в ретраями з коробки
2. Cypress дає прямий доступ до всіх API користувача напряму з контекста додатку і речі по типу сета кукі або стореджа в Cypress імплементовані набагато краще і легше. Я вже мовчу про persistent стейт
3. Cypress вміє в component testing, і досить добре (якщо PW також вміє, то відбій, але тут я не в курсі)
4. Якщо не використовувати вкладеності (ака callback hell, якщого можна досить легко уникнути), код Cypress насправді є більш читабельним, наприклад `cy.get(selector).should(’be.visible’).and(’have.text’, text)`

Ще, до речі, PW набагато краще справляється з будь-якими видами дрег енд дропу. Тут тема схожа з хавером: додатки часто імплементують це по-різному, і нативні події просто не вивозять. PW через CDP ж справляється завжди на відмінно

Це так, що прийшло в голову після прочитання, а так дискутувати тут можна довго. У PW неймовірно велика перевага в тому, що розробляє його Microsoft, який відомий відносно безкорисливими внесками в опен сорс спільноту, тому проблем з фінансуванням і рішенням, як підтримувати розробку, у команди PW немає :)

Дуже крута стаття!🔥 все по фактам)
В мене на проєкті була схожа ситуація, якийсь час писали на cypress, а потім вирішили протестувати playwright і порівняти роботу. Після тесту одразу перейшли на playwright! Головними причинами переходу були:
— швидкість — в наших кейсах різниця була в 2 рази
— стабільність — загалом тести стали менш флекі, але це, можливо, через iframe про які в наступному пункті
— iframe — оскільки покривати тестами треба було веб-додатки Microsoft (dynamics 365, CRM...) і, хто стикався з ними, той знає, як багато там iframe. І яке ж полегшення я відчув при написанні тестів на цих додатках саме з playwright... словами не передати)

Також за моїми спостереженнями playwright з кожним оновленням стає все краще і майже кожен раз додають щось цікаве, а головне — корисне.

В кінці хочу додати, що кожна тула по-своєму хороша! Обирайте те, що вам найбільше підходить.

Цікаво, скільки реально часу зайняло переписування 90 кейсів, та як це можна спростити

Переглянув по комітах — ми переписали всі тести за два тижні. Плюс ще деякий час робились мінорні правки у конфігах, fixtures i CI/CD workflows.

Нам було простіше, оскільки тест кейси були готові і було ± гарне розуміня, що ми хочемо від E2E тестів. Потрібно було лише переписати це все на іншу технологію.

Радий, що розробники теж пишуть статті як вони пишуть такі тести та все по ділу

Лиш доповню трошки, Сайпрес то опенсорсний тул, але це стартап і коли він збанкрутіє — то сайперс батьківська контора підтримувати його перестане лиш ентузіасти потенційно продовжать.
Хоча це напевно і на краще буде, коли сайперс не буде ставити палки в колеса людям з фіксом багів самостійним, з завантаженнями файлів, роботою з табами, браузерами, ну і прибрати б ще їх кастомну реалізацію просів

Дякую. Зберг в обране, буду кидатися в людей цим матеріалом )

Дякую за статтю, не зрозумів які саме еджкейси вас відштовхнули? Було б не погано написати їх, приклади коду і рішення

Дякую за відгук!

Cаме еджкейси, загалом, описані у пункті «8. Обмеження Cypress». Можна виділити:
— непідтримка декількох вікон (було неможливо протестувати авторизацію через сторонні auth providers).
— обмежена підтримка cross-origin тестування (Сypress нестабільно вів себе на інших доменах)
— обмежена підтримка iframes
— потреба у додаткових пакетах (realHover & realClick, visual testing)

Дякую за порівняння 🚀
чи можна в Playwright писати компонентні тести як в Cypress?

Так, але з купою обмежень...

Ні playwright, ні cypress не реалізує нормально компонентного тестування — краще піднімати Storybook й проклацувати його як самостійний додаток.

Існуючий тестранер в Storybook майже ні з чим нормально не інтегрований... там нахардкожено Playwright + Vite.

Якщо вам потрібно інтегрувати Cypress E2E-тести в CI/CD pipeline і/або реалізувати їхній паралельний запуск, ви маєте використовувати Cypress Cloud — комерційне рішення від Cypress, вебзастосунок для зберігання і аналізу тест-ранів.

А можете использовать официальные докер образы для прогона тестов.

У Cypress есть критическая проблема, про которую вы не упомянули: faky тесты. А еще эта адская балалайка иногда намертво зависает во время выполнения тестов (особенно если эти тесты сложные)

Ну и вишенка на тортике — поддержка Safari в Cypress реализована через ооочень странное место.

Cypress планувався й розроблявся як браузерне монетизоване розширення до Хрому, але йому відмовили в фінансуванні — звідси й обмеження.

Через таке ж саме як і в playwright (у них однакова реалізація підтримки safari)

Я в курсе, через playwright-webkit (то есть Cypress тянет наработки конкурента)

я би ще додав можливість розширення тестів в плейврайт через фікстури, та те що плейварайт теж обзавівся своїм (доволі простим правда) сервісом на азурі — github.com/...​laywright-testing-service

Дякую за доповнення!

Fixtures ми самі використовуємо на проекті. Дуже зручна фіча, коли є повторювані pre-conditions для тестів (наприклад, користувач авторизований).

романтические комиксы — это типа хентай манги? ведь в романтических новеллах должны быть нефритовые стержни сплош и рядом
обложки книг на сайте впечатляют :)

Лишу це й ось це тут.

K6 пробували ?

Дякую за коментар!

Не знав про існування таких extensions. Якщо вони працюють — супер, але бачу, що зараз достатньо мало користувачів і їх надійність під питанням. Плюс ще один інструмент не з під коробки Cypress.

З K6 досвіду не було.

Користувачів достатньо.
Спеку хром рекордера доводиться доводити вручну... але це значно спрощує методику тестування, бо всі Test Suite’и записуються як JSON файли, й взагалі не залежать від цільового фреймворку.

Кодогенератора за потреби можна написати самостійно... там досить проста схема в puppeteer replay. Кодогенератори в cypress / playwright / webdriverio також доступні як окремі ліби, й їх можна ганяти як npm задачу.

Спека хром рекордера не ідеальна — є що обгорнути й покращити, але якщо стрибаєте між фреймворками — варто задумуватись про якийсь рівень абстракції й відповідні інтерпретатори / кодогенератори.

Про k6 відписав нижче.

Ми використовуемо к6 для лоад тестів нашого бекенду. Його не зручно використовувати для е2е тестів які потребують браузер.

Він трохи обернено сумісний з Playwright сервером на гошці... зараз puppeteer / playwright розробники контрібьютять сумісність, й його можна використовувати разом з Playwright.

Два лівих ектеншена на 10к завантажень на обидва та ліба для лоаду.
До чого ви це написали, чи то ваші екстеншени? )

Чудова стаття, буду юзати як шпору перед собесами

Playwright почав активно набирати популярність останні шість місяців.

Playwright вже, можна сказати, став стандартом у автоматизації тестування, а не «почав набирати популярність»

Дякую за коментар!

Тут я вказував на те, що за останні шість місяців Playwright у світі JS дуже стрімко почав набирати кількість завантажень.

Відповідно до npmtrends за тиждень встановили:

Cypress 5м у серпні 2023
Playwright 1.4м у серпні 2023

Cypress 5.2m у лютому 2024
Playwright 3.8м у лютому 2024

За весь напрямок автоматизації тестування не можу говорити, тому, можливо, ви праві.

У лютому 2024 🤔
Тобто за 1е лютого встановили сайпрес 5лямів?

Скоріше в лютому дані за повний січень

дуже змістовний огляд, по-більше б такого аналізу з практичними прикладами!

Підписатись на коментарі