E2E-тестування за допомогою Playwright та Cucumber

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

Добрий день, 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-тестів та дізнатися їхній статус, що дозволяє швидко виявляти та реагувати на помилки.

Сподіваюся, стаття була корисною! Приємного використання!

Посилання

👍ПодобаєтьсяСподобалось3
До обраногоВ обраному8
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

Користуюсь вже років 10 gherkin/cucumber. Дуже зручно. Ідеальний інструмент для тестування API. Для тестування фронта він не дуже, занадто складно виходить. Кроків безліч і різних. З апі ж простіше, всі кроки однотипні, як запити так і перевірки. По суті маєш 10-20 степів, а далі просто компонуєш як треба. Виходять прості, компактні сценарії. Відкрив і одразу видно, що тестуєм, які дані надсилаєм, що очікуєм. Онбордити на проект чи передавати/шерити тести на gherkin/cucumber досить просто. Це все суто про API тестування з мого досвіду.

просто нонсенс, всі зі всіх щєлєй кажуть шо то прутня а ви кажете, шо норм
Якщо ми кажемо про комплексні АПІ тести де є інтеграція певної кількості сервісів в одному тесті, якщо є багато кроковий в принципі тест кейс — застрелитись можна із передачею даних між кроками огірковими. Тому це брехня що зручно вести АПІ тести для комплексних сенаріїв, а не для юніт теста на круд ресурса

І ітого в одному місці кроки в іншому місці реалізація, в третьому ще якась абстракція або дебільніша реалізація.

Ніхто окрім автоматизатора не дивляться в результати прогону тестів, а при тому всі менеджери хочуть розуміти шо там накодили ті ароматизатори і ітого ніхто ніц не розуміє.

Просто фасад в окремому класіку зробити над кроками і все ідеально читається. І взагалі це девелопери мають дивитись в результати прогону автотестів — ібо деви косячать та мають фіксити ті автотести коли ніц не заводиться після рефакторінга або нової фічі

Це ваш досвід, можливо ви користувались невдалою реалізацією gherkin, чи вели legacy проекти з кривою структурою. У мене проблем не було. Сценарії були і прості і геть складні типу чекауту з рефандами. З бібліотек використовув cucumber + pactumjs aбо behat + різні плагіни.

Ну я так скажу, це скорше ви виняток з правила і в вас все було ок, аніж у відверто більшості людей
Геркін придумали щоб стандартизувати комунікацію технарєй з не технарями, бдд придумали щоб це поставити на рейки та мати все обмазано огірком. Ітого якщо лиш одні люди в одній частинці юзали геркін — це 99% випадків виходило щось не реальне у підтримці.

А до прикладу якщо казати що так простіше читати що впало в тесті, я не перепрошую, але здебільшого стектрейсу вистачає, щоб зробити що пішло не так, аніж городити ще спек файл над простою функцією

Але знову ж таки повторюсь, це ви виняток з правила, що вам зайшло. ВИ напевно четверта людина яка рада тому огірку в тестах, я багато з ким спілкувався та співбесід перепровів, ніхто не в захваті

Зараз наші QA теж розглядають Cucumber. Бачу у коментарях багато негативу, але що є конкретною альтернативою, що працює добре? Дякую.

Альтернатива — не використовувати цей безглуздий додатковий layer of complexity.
Називайте зрозуміло методи в умовних PageObjects.
Для поєднання операцій, які описують повторювані юзер флоу, використовуйте Actions / Executors підхід.
Лінкуйте тест кейси к тест файлам (в describe / it / за допомогою аннотацій чи декораторів) і буде вам щастя та прозорість покриття.

Чим меньше коду, чим простіші тести — тим краще. Тому додатковий прошарок на gherkin без налаштованого процесу bdd в команді — оверхед. Треба враховувати, як інші люди будуть підтримувати і дебажити ці тести.
З назви тесту має бути зрозуміло, що тестується і який очікується результат.
З коду теста має бути зрозуміло, що сетапиться в тестах, які виконуються дії, перевірки.
З тест-репорту має бути зрозуміло, який поточний стан продукту в певній бранчі.

Якщо Cucumber це ще окей, то Робот це абсолютне збочення, вибачте...

Якщо Cucumber це ще окей, то Робот це абсолютне збочення, вибачте...

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

Ну це все одно, що сказати мені подобається білий колір а вам сірий. Уже другий коммент тут звучить що робот це типу дно, але ніхто не може аргументувати чому?)

Мови програмування насправді це не складно і навіть грамотний продакт овнер може їх нормально читати. Тому нафіг зайвий DSL
А от щоб було зручно читати та модифікувати є купа корисних паттернів типу Page Object

Мови програмування насправді це не складно

тут згоден

грамотний продакт овнер може їх нормально читати

а ось тут не згоден ) Бо залежить від того як той код написаний. Можна без кукумберів написати так, що все буде зрозуміло, а можна на чому хочеш написати, шо буде гірше брейнфака

Власне хз чого така нелюбов і хейт до кукумберу. Так хороші тести писати не просто і для цього сюрприз сюрприз теж треба навички, але чим же він так завинив ідеологічно тут хз. Якось думав запроватити на проекті але ідея здулася бо кейсів для мануального тестування було біля 200, а на один нормально описаний автоматичний кейс шло десь 4 години. Можлоиво якщо вже набити руку то можна вкластися в 2 години в середньому але все ще дуже дофіга часу і підтримку в актуальному стані ніхто ж не відміняв, а це все час і гроші. От з чим стикнувся і що він ніяк не може допомогти вірішити це скажімо флоу підписки на сервіс тут хоч вішайся хоча це взагалі жодна енд ту енд автоматизація нормально не покриє.

Власне хз чого така нелюбов і хейт до кукумберу.
Якось думав запроватити на проекті але ідея здулася
а на один нормально описаний автоматичний кейс шло десь 4 години

Тобто ви самі собі відповіли на питання? )

Тобто ви самі собі відповіли на питання? )

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

тут начебто в коментарях навели достатньо аргументiв

На одному з проєктів на рівні QA-гільдії було заборонено не рекомендували використовувати BDD для автоматизації, за винятком випадків, коли клієнти прямо цього вимагали)

«Кукумбар, sir!» — викиньте це лайно будь ласка.

Cucumber

Будь ласка, досить

Думав вчора написати комент за кукумбер, але думаю, може в мене тільки таке ставлення до нього. Зайшов глянути коменти, а тут все нормально)

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

Я думаю, що його до сих пір продають консалтингові компанії в рамках підходу BDD. Інше питання, що потім той кукумбер використовують тільки QA, а інші процеси не змінюють.

Ну бачив навпаки — BDD є причому реальне, майже по канонам. А огірка нема

1.

Cucumber is dead
The last remaining person who was working on the project has been laid off

www.reddit.com/...​133hpsh/cucumber_is_dead

2. Єдиний плюс cucumber — в тому що він змушує розбивати тест на кроки. Але а) ви й так само можете робити це звичайним кодом, викликати функцію напряму, а не використовувати незрозумілу прослойку. б) На практиці програмісти все одно пишуть чомусь величезну незрозумілу мешаніну з моків та асертів, тільки тепер туди ще вкинута прослойка cucumber.

3. Усі спроби просунути cucumber як щось навіть просто типу доки, для тестувальників хоча б — фейл, ніхто не хоче ним користуватись.

Cucumber is dead
The last remaining person who was working on the project has been laid off

www.reddit.com/...​133hpsh/cucumber_is_dead

Божечки, яка гарна новина! Сподiваюсь це гiвно похоронять назавжди

Та хоронять мабуть із дня появи. Щось досі ніяк не похоронять.

і ще, нещодавно вийшла така штука як test.step("Ololo step")
і жоден кукумбер не знадобиться в дупці проєкту)

я так розумію

Playwright

це альтернативо для Selenium.
які його переваги?

швидше, калосально швидше
менше впливає на роботу вебу апки
тресінг тестів, рекордер краще
мокати хттп, гракд, вебсокети можна
та купа інших переваг є

Треба поексперементувати.
Цікаво швидкодію Selenium на чому міряли? Selenoid?

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

Давай за швидкість з тобою не погоджусь ) Верніше погоджусь, він дійсно швидше, але як перевага... Не знаю на яких проєктах ти працював, але там, де я був, різниця в швидкості між селеніумом і пв була б 0,05% від тест рана ) Бо більшість часу йде на рендерінг, відповідь від сервара і т.д. Якщо все нафіг замокано і по мережі нічого не бігає ну тоді трошки більше буде )

github.com/...​test/java/io/testomat/web
давай спробуємо на реальному продакшн проєкті, де є прелоадери між сторінками де є асинхроне підвантаження даних
і так розсудимо — що швидше
я не можу повірити в твої цифри, лише якщо це не статична сторінка лише
оскільки ПВ комунікує через сокет з девтулз протоколом(по суті із бразуером) і це двостороння комунікація, селеінум по в3ц драйвер протоколу заснований на ХТТП — і це комунікація одностороння в селеніума

а особливо коли ми говоримо про ремоут запуск через грід або селеноід в нас ще одна ланка зʼявляється через яку тести ще повільніше працюють

можемо ще перевірити як швидко тести ті самі працюватимуть і на ремоуті на браузер стек або саус лаб

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

В тому то і справа, шо не статична. Якби була статично, то була б більше видна різниця. Нещодавно тест зробив. Досить простий, але на 20 секунд. Там дій дійсно не багато. Тест на пв. Чого так довго — енв тугий. Але можливо то в мене проєкти такі трапляютсья )

В сусідній темі міряли швидкість, різниця вийшла в 1.6 рази на користь PW.

Ще Playwright дає можливість автоматизації тестування API, у Селеніума цього немає

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

Перш за все він не застарілий, синтаксис простіший. Типу коли в селеніумі є купа стратегій для вибору локатора, а в тому ж playwright чи WebdriverIO — один метод який все обробляє під капотом.

ти точно по плейрайт кажеш, що він простіше?)

угу, я починав в автоматизації з webdriverIO потім Playwright і вони схожі за використанням. Потім я мав проєкт понад рік на selenium, і різниця відчувається одразу, використовувати якісь кастомні модулі важко, менеджети великі проєкти і великі РОМ — теж, модуляцію нормальну не зробиш.

WDIO/Playwright має з коробки більшу кількість можливостей що не дає selenium

І особисто мені сленіум виглядає неймовірно старо і важчий порівняно з новими фреймворками

На декiлькох проектах його заводили, навiть бувало тестiв понаписували, але пiзнiше завжди закидували

Чому закидували? І закидували BDD чи Playwright?

Закидували bdd. Створення нових і підтримка існуючих тестів вимагала забагато еффортів. І завжди знаходилися більш пріоритетні задачі для тестінг тім. Чомусь менеджмент завжди вважав на початку, що такі тести будуть дуже прості. Але по факту вони були доволі складними.

Якщо можна попросити, будь ласка, наведіть приклад такого тесту, де ’відмова від BDD’ покращувала автоматизацію. (До речі, я дуже люблю працювати з Python Behave для e2e)

Якщо можна попросити, будь ласка, наведіть приклад такого тесту, де ’відмова від BDD’ покращувала автоматизацію

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

До речі, я дуже люблю працювати з Python Behave для e2e)

Congrats

Я вибачаюсь, я не хотіла написати питання так, щоб вас образити. Я просто хотіла попросити приклад. Ще раз вибачаюсь.

давайте підем від зворотнього: наведіть, будь ласка, приклад такого тесту, де «прихід BDD» покращив автоматизацію (до речі, я жахливо не люблю BDD)

Альтернатива — Robot Framework. Степи зрозумілі на простому англ і можна сказати те ж BDD але без обгортки тому що цей фреймворк і так в стилі BDD. Як результат тести завжди зрозумілі і виглядають як степи в тест кейсі і головне що писати і підтримувати тести дуже швидко

Так а що не подобається?) Аргументи в студію

Я 9 років шукаю приклад навпаки, ду кукумбер то поліпшує )

Думаю ідея полягала в тому, що оті високорівневі тести «ін плейн інгліш» пишуть не кодерки, а продакт піпл (а сама реалізація степів в коді не вимагає занадто високого оверхеду для підтримки). В реалі все майже навпаки: що кукумбер кодерки пишуть самі для себе, що реалізація шагів в коді перетворєються на крихке складно підтримуване лайно, плюс, значний оверхед (воно ж ще й повільне як холера).

Я мав «задоволення» з тим лайном працювати. Так воно все і є )

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

Ну є рішення — пошук степів (методів) за допомогою Ctrl + Shift + F. Те що степи схожі це вже проблема реалізації цих методів (степів)

пошук степів (методів) за допомогою Ctrl + Shift + F

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

Якщо методів купа — то треба писати регулярку. Швидкість пошуку по тексту відповідна, а коли проектів купа... І все це замість простого «Go to implementation» в коді.

Не поняв нашо мені регулярка для методів )

Пане, а як ви визначили що вам потрібен кукумбер?
Ви працюєте з BDD? Є колаборація між БА, левами та тестуванням? Ви разом пишите сценарії?

Cucumber це люте дніщє. Продактовнери все одно ним не користуються потім.

Огірок... Співчуваю всім кому його доводиться використоувувати без БДД як процесу

На всіх проектах, де зустрічав bdd, приходили до одного висновку — позбутись цього непотрібного прошарку якнайшвидше. Але ж людям подобається, такий собі маркетинг, хоч ba/po в душі не гребуть що воно таке і не збираються ним користуватись. Писати тести заради тестів.

у нас зараз лід вирішив, шо йому по пріколу впихнути ще кукумбер — продакти сказали, що не будуть писати Acceptance criteria у форматі геркін, але йому пофіг)))

Яка компанія кажете?)

ноу нейм)))

тут цікаво шоб раптом в той ноунейм не потрапити ) Мої співчуття до речі )

якщо побачите бельгійський стартап у сфері фінтех — тікайте)))

Середу чи середовище для тестування?
Перекладайте з англійської, будь-ласка, менше сюрпризів буде

від авторів «пекельні борошна» :D

Дякую за ваш коментар! Виправили одруківку.

Я не перекладав цю статтю з англійської. Вибачаюсь за помилку.

це мали редактори підказати)) тут вашої вини нема)

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