E2E-тестування за допомогою Playwright та Cucumber
Добрий день, DOU комʼюніті! Мене звати Микита Парфенчук, я Senior Software Engineer в SoftServe. Сьогодні хочу поділитися своїм досвідом налаштування та використання фреймворку для вебтестування Playwright разом з таким інструментом, як Cucumber.
На проєкті, де я працюю, дуже прискіпливо ставляться до E2E-тестування: для нас важливо покрити тестами якомога більше різних use case нашого вебсервісу, мати змогу автоматично їх виконувати, налаштовувати, бачити результат та запускати їх у різних браузерах. Тому проаналізувавши всі інструменти для вебтестування ми вирішили, що саме Playwright в поєднанні з Cucumber — це саме те, що нам треба. А зараз більш детально розглянемо кожен з них.
Чому саме Playwright та Cucumber
Playwright — це фреймворк для вебтестування та автоматизації, який підтримує такі механізмі візуалізації, як Chromium, Firefox і WebKit та надає API для роботи з ними. Це означає, що можна запустити тести одразу в декількох веббраузерах, не турбуючись про відмінності в поведінці. Також Playwright підтримує:
— основні мови програмування;
— емуляцію мобільних браузерів;
— підключення через Chrome DevTools Protocol;
— кросплатформеність;
— налаштування контексту браузера;
— комплексний API, який дозволяє різноманітно взаємодіяти з елементами сторінки;
— потужні інструменти для інспектування тестів.
Cucumber — це популярний інструмент тестування, який використовує Behavior-Driven Development (BDD) підхід до тестування та Gherkin-синтаксис для написання тестів, що дозволяє вказувати очікувану поведінку простою та зрозумілою мовою. Він також підтримує написання тестів за допомогою JavaScript та TypeScript.
Створюємо проєкт
Що ж, перейдімо до практики та перевіримо можливості даних інструментів на прикладі. Для початку створимо новий проєкт. Використаємо npm-менеджер пакетів:
mkdir e2e-testing && cd e2e-testing
npm init -y
Далі встановимо Playwright:
npm i -D @playwright/test
# install supported browsers
npx playwright install
А також Cucumber.js:
npm i -D @cucumber/cucumber
Щоб проєкт підтримував TypeScript, встановимо такі пакети:
npm i -D ts-node @types/node
Налаштування Playwright та Cucumber
Почнемо з того, що налаштуємо середовище тестування, у якому ми будемо писати E2E-тести. Створим файл world.ts, де визначимо основні змінні, які будуть використовуватися в кожному сценарії.
import {World,
setDefaultTimeout,
setWorldConstructor,
IWorldOptions,
} from "@cucumber/cucumber";
import { Browser, BrowserContext, Page } from "@playwright/test";
export default class ExampleWorld extends World {browser!: Browser;
browserContext!: BrowserContext;
page!: Page;
constructor(options: IWorldOptions) {super(options);
}
} setDefaultTimeout(10 * 1000); // increase timeout for some cases
setWorldConstructor(ExampleWorld);
Далі створимо хуки в файлі hooks.ts, які будуть виконуватися до та після кожного сценарію. Перед кожним тестом буде створюватися нова сторінка браузера, а сам процес виконання буде записуватися та зберігатися в папці videos/. Також у випадку виникненні помилки буде зроблений скриншот сторінки та збережений в папці screenshots/errors/. Усе це допомагатиме нам бачити результат тестів та відстежувати помилки. Наприкінці кожного сценарію браузер закривається.
import { Before, After, AfterStep, Status } from "@cucumber/cucumber";import { Browser, chromium, devices, firefox, webkit } from "@playwright/test";
import ExampleWorld from "./world";
const createBrowser = (browserType: string): Promise<Browser> => { switch (browserType) {case "chromium":
return chromium.launch();
case "firefox":
return firefox.launch();
case "webkit":
return webkit.launch();
default:
throw new Error(`Unknown browser type: ${browserType}`);}
};
Before<ExampleWorld>(async function (this, scenario) {const targetDevice = devices[this.parameters.device];
if (!targetDevice) { throw new Error(`Unknown device type: ${this.parameters.device}`);}
this.browser = await createBrowser(targetDevice.defaultBrowserType);
this.browserContext = await this.browser.newContext({...targetDevice,
recordVideo: { dir: `videos/${scenario.pickle.name}` },});
this.page = await this.browserContext.newPage();
});
AfterStep<ExampleWorld>(async function ({ result, pickle }) { if (result.status === Status.FAILED) { await this.page.screenshot({ path: `screenshots/errors/${pickle.name}.png`,});
}
});
After<ExampleWorld>(async function (this) {await this.page.close();
await this.browserContext.close();
await this.browser.close();
});
Потім створимо файл cucumber.js з налаштуваннями для виконання майбутніх тестів. Тут ми визначимо базові налаштування та типи девайсів, які ми будемо використовувати. Повний перелік доступних девайсів можна знайти тут.
const commonOptions = {requireModule: ["ts-node/register"],
require: ["world.ts", "hooks.ts", "features/**/*.step.ts"],
formatOptions: {snippetInterface: "async-await",
},
};
const profiles = { desktop: {device: "Desktop Chrome",
},
ios: {device: "iPhone 14 Pro",
},
android: {device: "Pixel 5",
},
};
const options = {};for (const profile in profiles) { options[profile] = {...commonOptions,
worldParameters: {device: profiles[profile].device,
},
};
} module.exports = options;
Відкриємо package.json та зазначимо команди для виконання тестів на різних девайсах:
"scripts": {"test:desktop": "cucumber-js --config cucumber.js --profile desktop",
"test:ios": "cucumber-js --config cucumber.js --profile ios",
"test:android": "cucumber-js --config cucumber.js --profile android"
}
Пишемо тести
Усі наші тести будуть розміщені в папці features/. Створимо сценарій у файлі example.feature, який би перевіряв title вказаних сторінок. Використаємо Gherkin-синтаксис.
Feature: What is the page title? Scenario Outline: The page contains a specific title
Given url is "<url>"
When I open the page
Then it should have a "<title>" title Examples:
| url | title |
| https://playwright.dev/ | Fast and reliable end-to-end testing for modern web apps \| Playwright |
| https://cucumber.io/ | BDD Testing & Collaboration Tools for Teams \| Cucumber |
А також напишемо сам тест у файлі example.step.ts, що безпосередньо перевіряє title сторінок.
import { Given, When, Then } from "@cucumber/cucumber";import { expect } from "@playwright/test";
import ExampleWorld from "../world";
interface ExampleStep extends ExampleWorld {url: string;
}
Given<ExampleStep>("url is {string}", async function (givenUrl: string) {this.url = givenUrl;
});
When<ExampleStep>("I open the page", async function () {await this.page.goto(this.url);
}); Then<ExampleStep>(
"it should have a {string} title", async function (expectedTitle: string) {await expect(this.page).toHaveTitle(expectedTitle);
}, );
Що ж, запустімо наш E2E-тест! Спершу перевіримо наші сценарії на Desktop:
npm run test:desktop
Очікуваним результатом буде:

Тепер перевіримо наші сценарії на iOS:
npm run test:ios
Очікуваним результатом буде:

Зрештою перевіримо наші сценарії на Android:
npm run test:android
Очікуваним результатом буде:

А сам процес виконання тестів буде записаний та збережений в папці videos/ для кожного сценарію:

Як бачимо, налаштувати проєкт з Playwright та Cucumber нескладно, його можна масштабувати чи додати до того, що існуює.
Що далі
Щоб автоматизувати процес виконання тестів, можна додати виконання створених команд до CI/CD та створити можливість збереження результатів тестів до хмарного сховища. Наприклад, на нашому проєкті ми створили свій власний вебзастосунок, який використовує файли результатів тестів (що завантажуються до Amazon S3 під час перевірки нової збірки) та дозволяє переглянути статус усіх сценаріїв для вказаних девайсів. Таким способом будь-який розробник чи навіть стейкхолдер може подивитися на результат виконання E2E-тестів та дізнатися їхній статус, що дозволяє швидко виявляти та реагувати на помилки.
Сподіваюся, стаття була корисною! Приємного використання!
78 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарівКористуюсь вже років 10 gherkin/cucumber. Дуже зручно. Ідеальний інструмент для тестування API. Для тестування фронта він не дуже, занадто складно виходить. Кроків безліч і різних. З апі ж простіше, всі кроки однотипні, як запити так і перевірки. По суті маєш10-20 степів, а далі просто компонуєш як треба. Виходять прості, компактні сценарії. Відкрив і одразу видно, що тестуєм, які дані надсилаєм, що очікуєм. Онбордити на проект чи передавати/шерити тести на gherkin/cucumber досить просто. Це все суто про API тестування з мого досвіду.
просто нонсенс, всі зі всіх щєлєй кажуть шо то прутня а ви кажете, шо норм
Якщо ми кажемо про комплексні АПІ тести де є інтеграція певної кількості сервісів в одному тесті, якщо є багато кроковий в принципі тест кейс — застрелитись можна із передачею даних між кроками огірковими. Тому це брехня що зручно вести АПІ тести для комплексних сенаріїв, а не для юніт теста на круд ресурса
І ітого в одному місці кроки в іншому місці реалізація, в третьому ще якась абстракція або дебільніша реалізація.
Ніхто окрім автоматизатора не дивляться в результати прогону тестів, а при тому всі менеджери хочуть розуміти шо там накодили ті ароматизатори і ітого ніхто ніц не розуміє.
Просто фасад в окремому класіку зробити над кроками і все ідеально читається. І взагалі це девелопери мають дивитись в результати прогону автотестів — ібо деви косячать та мають фіксити ті автотести коли ніц не заводиться після рефакторінга або нової фічі
Це ваш досвід, можливо ви користувались невдалою реалізацією gherkin, чи вели legacy проекти з кривою структурою. У мене проблем не було. Сценарії були і прості і геть складні типу чекауту з рефандами. З бібліотек використовув cucumber + pactumjs aбо behat + різні плагіни.
Ну я так скажу, це скорше ви виняток з правила і в вас все було ок, аніж у відверто більшості людей
Геркін придумали щоб стандартизувати комунікацію технарєй з не технарями, бдд придумали щоб це поставити на рейки та мати все обмазано огірком. Ітого якщо лиш одні люди в одній частинці юзали геркін — це 99% випадків виходило щось не реальне у підтримці.
А до прикладу якщо казати що так простіше читати що впало в тесті, я не перепрошую, але здебільшого стектрейсу вистачає, щоб зробити що пішло не так, аніж городити ще спек файл над простою функцією
Але знову ж таки повторюсь, це ви виняток з правила, що вам зайшло. ВИ напевно четверта людина яка рада тому огірку в тестах, я багато з ким спілкувався та співбесід перепровів, ніхто не в захваті
Мені особисто той огірок також дуже сподобався. І між кроками передачу даних також можна зробити при бажанні. Я таке робив раніше. Питання лишень в конкретному завданні: що саме треба передавати. Правда, як на мене, огірок ліпше всього підійде для UI/e2e-тестів, ніж для апішки. Але при бажанні можна і туди приліпити.
Це ж зайвий рівень абстракції, вам не лінь ото все підтримувати?
Зараз наші QA теж розглядають Cucumber. Бачу у коментарях багато негативу, але що є конкретною альтернативою, що працює добре? Дякую.
Альтернатива — не використовувати цей безглуздий додатковий layer of complexity.
Називайте зрозуміло методи в умовних PageObjects.
Для поєднання операцій, які описують повторювані юзер флоу, використовуйте Actions / Executors підхід.
Лінкуйте тест кейси к тест файлам (в describe / it / за допомогою аннотацій чи декораторів) і буде вам щастя та прозорість покриття.
Чим меньше коду, чим простіші тести — тим краще. Тому додатковий прошарок на gherkin без налаштованого процесу bdd в команді — оверхед. Треба враховувати, як інші люди будуть підтримувати і дебажити ці тести.
З назви тесту має бути зрозуміло, що тестується і який очікується результат.
З коду теста має бути зрозуміло, що сетапиться в тестах, які виконуються дії, перевірки.
З тест-репорту має бути зрозуміло, який поточний стан продукту в певній бранчі.
robot framework норм рішення
Якщо Cucumber це ще окей, то Робот це абсолютне збочення, вибачте...
Як цікаво виходить, коли в модулі Коментарі на головній форуму не відображається назва теми, від чого коментар набуває зовсім інакшого змісту.
Ну це все одно, що сказати мені подобається білий колір а вам сірий. Уже другий коммент тут звучить що робот це типу дно, але ніхто не може аргументувати чому?)
Мови програмування насправді це не складно і навіть грамотний продакт овнер може їх нормально читати. Тому нафіг зайвий DSL
А от щоб було зручно читати та модифікувати є купа корисних паттернів типу Page Object
тут згоден
а ось тут не згоден ) Бо залежить від того як той код написаний. Можна без кукумберів написати так, що все буде зрозуміло, а можна на чому хочеш написати, шо буде гірше брейнфака
Власне хз чого така нелюбов і хейт до кукумберу. Так хороші тести писати не просто і для цього сюрприз сюрприз теж треба навички, але чим же він так завинив ідеологічно тут хз. Якось думав запроватити на проекті але ідея здулася бо кейсів для мануального тестування було біля 200, а на один нормально описаний автоматичний кейс шло десь 4 години. Можлоиво якщо вже набити руку то можна вкластися в 2 години в середньому але все ще дуже дофіга часу і підтримку в актуальному стані ніхто ж не відміняв, а це все час і гроші. От з чим стикнувся і що він ніяк не може допомогти вірішити це скажімо флоу підписки на сервіс тут хоч вішайся хоча це взагалі жодна енд ту енд автоматизація нормально не покриє.
Тобто ви самі собі відповіли на питання? )
Та ні, це був суто економічний розрахунок і вирішили що воно просто того не варте, а тут в темі багато хейту який мені не дуже зрозумілий і цікаво чому його так нелюблять. Були б ресурси можна було б зробити нормально. Одна з причин чому це займало багато часу це те що на той час не було адекватного врапера для управління браузером. Навіть форми заповнювати було іноді складнувато.
тут начебто в коментарях навели достатньо аргументiв
На одному з проєктів на рівні QA-гільдії
було забороненоне рекомендували використовувати BDD для автоматизації, за винятком випадків, коли клієнти прямо цього вимагали)Які були аргументи?
«Кукумбар, sir!» — викиньте це лайно будь ласка.
Будь ласка, досить
Думав вчора написати комент за кукумбер, але думаю, може в мене тільки таке ставлення до нього. Зайшов глянути коменти, а тут все нормально)
Але я помилився — коли уперше це побачив фіг зна коли одразу сказав що ця фігня ну точно не приживеться.
А про нього досі пишуть, розвивається, має комьюніті не маленьке. Дива та й годі.
Я думаю, що його до сих пір продають консалтингові компанії в рамках підходу BDD. Інше питання, що потім той кукумбер використовують тільки QA, а інші процеси не змінюють.
Ну бачив навпаки — BDD є причому реальне, майже по канонам. А огірка нема
1.
www.reddit.com/...133hpsh/cucumber_is_dead
2. Єдиний плюс cucumber — в тому що він змушує розбивати тест на кроки. Але а) ви й так само можете робити це звичайним кодом, викликати функцію напряму, а не використовувати незрозумілу прослойку. б) На практиці програмісти все одно пишуть чомусь величезну незрозумілу мешаніну з моків та асертів, тільки тепер туди ще вкинута прослойка cucumber.
3. Усі спроби просунути cucumber як щось навіть просто типу доки, для тестувальників хоча б — фейл, ніхто не хоче ним користуватись.
Божечки, яка гарна новина! Сподiваюсь це гiвно похоронять назавжди
Та хоронять мабуть із дня появи. Щось досі ніяк не похоронять.
і ще, нещодавно вийшла така штука як test.step("Ololo step")
і жоден кукумбер не знадобиться в дупці проєкту)
я так розумію
це альтернативо для Selenium.
які його переваги?
швидше, калосально швидше
менше впливає на роботу вебу апки
тресінг тестів, рекордер краще
мокати хттп, гракд, вебсокети можна
та купа інших переваг є
Треба поексперементувати.
Цікаво швидкодію Selenium на чому міряли? Selenoid?
Плейрайт працює з браузерами нативно, а Селеніум через окремий шар абстракції.
хоча б через сам факт цього він вже швидше.
Давай за швидкість з тобою не погоджусь ) Верніше погоджусь, він дійсно швидше, але як перевага... Не знаю на яких проєктах ти працював, але там, де я був, різниця в швидкості між селеніумом і пв була б 0,05% від тест рана ) Бо більшість часу йде на рендерінг, відповідь від сервара і т.д. Якщо все нафіг замокано і по мережі нічого не бігає ну тоді трошки більше буде )
github.com/...test/java/io/testomat/web
давай спробуємо на реальному продакшн проєкті, де є прелоадери між сторінками де є асинхроне підвантаження даних
і так розсудимо — що швидше
я не можу повірити в твої цифри, лише якщо це не статична сторінка лише
оскільки ПВ комунікує через сокет з девтулз протоколом(по суті із бразуером) і це двостороння комунікація, селеінум по в3ц драйвер протоколу заснований на ХТТП — і це комунікація одностороння в селеніума
а особливо коли ми говоримо про ремоут запуск через грід або селеноід в нас ще одна ланка зʼявляється через яку тести ще повільніше працюють
можемо ще перевірити як швидко тести ті самі працюватимуть і на ремоуті на браузер стек або саус лаб
може бути гарним демо відео, на якому в реальному часі ми побачимо наскільки трагічно швидше пацює плейрайт
В тому то і справа, шо не статична. Якби була статично, то була б більше видна різниця. Нещодавно тест зробив. Досить простий, але на 20 секунд. Там дій дійсно не багато. Тест на пв. Чого так довго — енв тугий. Але можливо то в мене проєкти такі трапляютсья )
В сусідній темі міряли швидкість, різниця вийшла в 1.6 рази на користь PW.
Ще Playwright дає можливість автоматизації тестування API, у Селеніума цього немає
Умовний axios теж дає таку можливість ) я б не сказав, шо то велика перевага. Це такий самий умовно клієнт, тільки вбудований.
Перш за все він не застарілий, синтаксис простіший. Типу коли в селеніумі є купа стратегій для вибору локатора, а в тому ж playwright чи WebdriverIO — один метод який все обробляє під капотом.
а Selenium Webdriver застарiлий?
ти точно по плейрайт кажеш, що він простіше?)
угу, я починав в автоматизації з webdriverIO потім Playwright і вони схожі за використанням. Потім я мав проєкт понад рік на selenium, і різниця відчувається одразу, використовувати якісь кастомні модулі важко, менеджети великі проєкти і великі РОМ — теж, модуляцію нормальну не зробиш.
WDIO/Playwright має з коробки більшу кількість можливостей що не дає selenium
І особисто мені сленіум виглядає неймовірно старо і важчий порівняно з новими фреймворками
На декiлькох проектах його заводили, навiть бувало тестiв понаписували, але пiзнiше завжди закидували
Чому закидували? І закидували BDD чи Playwright?
Закидували bdd. Створення нових і підтримка існуючих тестів вимагала забагато еффортів. І завжди знаходилися більш пріоритетні задачі для тестінг тім. Чомусь менеджмент завжди вважав на початку, що такі тести будуть дуже прості. Але по факту вони були доволі складними.
Якщо можна попросити, будь ласка, наведіть приклад такого тесту, де ’відмова від BDD’ покращувала автоматизацію. (До речі, я дуже люблю працювати з Python Behave для e2e)
Ваш коментар звучить як пасивно-агресивний наезд. Я не можу навести такого прикладу, бо я такого, як ви написали, не стверджувала. Я просто розказую факти, яким я була свідком на3-х великих проектах.
Congrats
Я вибачаюсь, я не хотіла написати питання так, щоб вас образити. Я просто хотіла попросити приклад. Ще раз вибачаюсь.
давайте підем від зворотнього: наведіть, будь ласка, приклад такого тесту, де «прихід BDD» покращив автоматизацію (до речі, я жахливо не люблю BDD)
Альтернатива — Robot Framework. Степи зрозумілі на простому англ і можна сказати те ж BDD але без обгортки тому що цей фреймворк і так в стилі BDD. Як результат тести завжди зрозумілі і виглядають як степи в тест кейсі і головне що писати і підтримувати тести дуже швидко
Така сама срака як i огiрок.
Так а що не подобається?) Аргументи в студію
Я 9 років шукаю приклад навпаки, ду кукумбер то поліпшує )
Думаю ідея полягала в тому, що оті високорівневі тести «ін плейн інгліш» пишуть не кодерки, а продакт піпл (а сама реалізація степів в коді не вимагає занадто високого оверхеду для підтримки). В реалі все майже навпаки: що кукумбер кодерки пишуть самі для себе, що реалізація шагів в коді перетворєються на крихке складно підтримуване лайно, плюс, значний оверхед (воно ж ще й повільне як холера).
Я мав «задоволення» з тим лайном працювати. Так воно все і є )
Був такий досвід. Перші три місяці я не міг жодного тесту написати не спитавши який степ мені треба використати, бо їх дохреналіон схожих, які працюють на різних сторінках. На яких — то треба тільки знати
Ну є рішення — пошук степів (методів) за допомогою Ctrl + Shift + F. Те що степи схожі це вже проблема реалізації цих методів (степів)
це жах. То, що воно мплементовано було жахливо, тут не посперичаєшся, але шукати методи то зло. Я не хочу шось шукати, я хочу звернутися до певного контекста і подивитися шо він там вміє, перейти в інший контекст, а у нього свої методи. Тоді не заплутаєшся як би ти ті методи не називав, але они обмежені певним контекстом.
Якщо методів купа — то треба писати регулярку. Швидкість пошуку по тексту відповідна, а коли проектів купа... І все це замість простого «Go to implementation» в коді.
Не поняв нашо мені регулярка для методів )
Пане, а як ви визначили що вам потрібен кукумбер?
Ви працюєте з BDD? Є колаборація між БА, левами та тестуванням? Ви разом пишите сценарії?
Cucumber це люте дніщє. Продактовнери все одно ним не користуються потім.
Огірок... Співчуваю всім кому його доводиться використоувувати без БДД як процесу
Я б скоротив до «співчуваю всім...»
На всіх проектах, де зустрічав bdd, приходили до одного висновку — позбутись цього непотрібного прошарку якнайшвидше. Але ж людям подобається, такий собі маркетинг, хоч ba/po в душі не гребуть що воно таке і не збираються ним користуватись. Писати тести заради тестів.
у нас зараз лід вирішив, шо йому по пріколу впихнути ще кукумбер — продакти сказали, що не будуть писати Acceptance criteria у форматі геркін, але йому пофіг)))
Яка компанія кажете?)
ноу нейм)))
тут цікаво шоб раптом в той ноунейм не потрапити ) Мої співчуття до речі )
якщо побачите бельгійський стартап у сфері фінтех — тікайте)))
Середу чи середовище для тестування?
Перекладайте з англійської, будь-ласка, менше сюрпризів буде
від авторів «пекельні борошна» :D
Дякую за ваш коментар! Виправили одруківку.
Я не перекладав цю статтю з англійської. Вибачаюсь за помилку.
це мали редактори підказати)) тут вашої вини нема)