BDD і Gherkin: обіцянки і реальність
Зміст
BDD і Gherkin продають як срібну кулю: пишете сценарії людською мовою «Given… When… Then», бізнес їх читає, тестувальник автоматизує, і в команди зʼявляється єдина жива документація, яка ніколи не бреше. На практиці ж чимало команд отримують зайвий шар над UI-тестами: ті самі крихкі кліки, тільки тепер загорнуті в англійські речення, які ніхто, крім AQA, не відкриває. Обіцянка й реальність розходяться не тому, що інструмент поганий, а тому, що плутають дві різні речі — практику й формат запису.
На співбесіді це улюблена пастка: «Що таке BDD?» — і слабкий кандидат відповідає «це коли пишемо тести на Gherkin через Cucumber». Сильний почне з того, що BDD — це передусім розмова, а Gherkin — лише спосіб її зафіксувати. Ця глава — про те, де межа між обіцянкою і реальністю, і як не платити за синтаксис, не отримавши вигоди.
BDD — це практика співпраці, а не синтаксис
BDD (Behavior-Driven Development, розробка через поведінку) виросла з TDD у середині 2000-х як спроба Дена Норта (Dan North) прибрати з TDD слово «тест», яке збивало новачків з пантелику. Ідея: описувати не тести, а очікувану поведінку системи прикладами, і робити це разом — до написання коду.
Центральний ритуал BDD — розмова, яку часто називають «три амігос» (three amigos): представник бізнесу (product owner, аналітик), розробник і тестувальник разом розбирають конкретну історію й проговорюють приклади її поведінки. Бізнес знає, що має статися; розробник — що реально можливо; тестувальник — що піде не так і які крайові випадки всі забули. Продукт цієї розмови — спільне розуміння, а вже його побічний артефакт — записані сценарії.
Ось ключ до всієї глави: цінність BDD створюється в розмові, а не в текстовому файлі. Якщо команда пропустила обговорення й просто написала Gherkin постфактум, «щоб було по-модному», вона заплатила повну ціну інструмента, не отримавши головного — вирівняного розуміння й ранньої ловитви непорозумінь. Формалізована техніка такої розмови — example mapping (Метт Вінн, Matt Wynne): беруть історію, виписують правила (rules), під кожне — приклади (examples), а незрозуміле складають у стос запитань (questions). Уже цей стос питань окупає зустріч: він показує діри у вимогах до того, як їх зашили в код.
Тому коректне визначення для співбесіди: BDD — це практика співпраці навколо конкретних прикладів поведінки; Gherkin, Cucumber, feature-файли — лише інструменти, які цю практику підтримують, але не замінюють.
Діаграма показує головне непорозуміння: Gherkin (крок C) — лише один вузол циклу. Команди, що впроваджують «BDD», часто стартують одразу з C, пропустивши A і B, — і дивуються, чому вигоди немає.
Given–When–Then: анатомія сценарію
Gherkin — це структурована майже-природна мова для запису прикладів. Її кістяк — три ключові слова:
- Given — контекст, стан світу до події (передумова). «Given користувач залогінений».
- When — подія або дія, що запускає поведінку. В ідеалі одна. «When він додає товар у кошик».
- Then — очікуваний спостережуваний результат. «Then у кошику один товар».
Кроки зчіплюють словами And і But. Спільний для всіх сценаріїв контекст виносять у Background. Приклад feature-файлу:
Feature: Кошик
Background:
Given користувач залогінений
Scenario: Додавання товару в порожній кошик
Given кошик порожній
When користувач додає товар "Клавіатура"
Then у кошику 1 товар
And сума кошика дорівнює ціні "Клавіатури"
Структура невипадкова: Given–When–Then один в один лягає на Arrange–Act–Assert з глави «Анатомія автотесту». Given — це підготовка стану, When — дія, Then — перевірка. Звідси й дисципліна, яку перевіряють на рев'ю: у Given не роблять асертів, у Then не тиснуть кнопок. Один сценарій — одна поведінка, а не десять кліків «за компанію».
Для параметризації є Scenario Outline з таблицею Examples — це той самий data-driven тест (див. главу про тест-дані):
Scenario Outline: Валідація пароля при реєстрації
When користувач реєструється з паролем "<password>"
Then система показує "<result>"
Examples:
| password | result |
| short | Пароль закороткий |
| goodpass123 | Реєстрація успішна |
Одне застереження термінології: Gherkin — це синтаксис і мова; Cucumber, SpecFlow, Behave, вбудований BDD у CodeceptJS — це інструменти, які цю мову виконують. Given–When–Then можна вживати як формат критеріїв приймання (acceptance criteria) навіть без жодного інструмента — просто в тікеті Jira.
Imperative проти declarative
Ось де вирішується доля всієї затії. Один і той самий сценарій можна написати двома способами.
Імперативний (imperative) — описує кроки інтерфейсу:
Scenario: Логін (імперативно)
Given користувач на сторінці "/login"
When він вводить "user@test.io" у поле "email"
And вводить "Qwerty123" у поле "password"
And натискає кнопку "Увійти"
Then він бачить заголовок "Мій профіль"
Декларативний (declarative) — описує намір, а «як» ховає в код кроків:
Scenario: Логін (декларативно)
Given зареєстрований користувач
When він входить у систему
Then він потрапляє у свій профіль
Різниця не косметична. Імперативний сценарій крихкий: перейменували поле, змінили верстку форми — і треба правити текст, який мав би читати бізнес. Він багатослівний і фактично дублює page object у прозі. Головне — він нечитабельний для нетехнічного читача: продакт-менеджер не хоче знати про поле «email», він хоче знати, що «користувач входить у систему».
Декларативний сценарій стабільний: зміна UI зачіпає лише визначення кроку (step definition), а не сам сценарій. Він читається як вимога, переживає редизайн і не тече деталями реалізації. Правило-орієнтир: у feature-файлі — мова бізнесу й наміри; уся механіка кліків і локаторів — нижче, у коді кроків.
Нюанс для сеньйора: занадто декларативно теж погано. Якщо весь сценарій це «When усе працює / Then все добре», він нічого конкретного не перевіряє — читається гарно, а тестова цінність нульова. Баланс: один сценарій — один бізнес-намір із конкретним, але не покроковим результатом.
Коли Gherkin виправданий, а коли це податок
Тепер чесно про ціну. Gherkin додає шар непрямування (indirection): feature-файл не виконується сам — кожен рядок треба привʼязати до функції-кроку, розпарсити параметри, підтримувати цей glue-код. Дебажити стає важче: падіння в кроці «When він входить у систему» доводиться розкручувати через кілька рівнів, а не читати прямо в тесті.
Кожна стрілка — місце, де може зламатися привʼязка й де губиться слід під час дебагу. Звичайний Playwright-тест має на один рівень менше: він одразу починається з рівня B.
Ця ціна окупається за конкретних умов:
- Є реальний нетехнічний читач. Продакт, аналітик, комплаєнс, замовник справді відкривають і читають сценарії або беруть участь у їх написанні. Це головна умова.
- Розмова відбувається насправді. Команда практикує «три амігос» / example mapping, і feature-файли народжуються з обговорення, а не пишуться AQA наодинці.
- Критерії приймання — спільний контракт. Given–When–Then живе у визначенні готовності історії, а не тільки в тестовому репозиторії.
І дзеркально — коли Gherkin стає чистим податком:
- Технічна AQA-команда пише сценарії сама для себе, і жоден нетехнічний колега їх ніколи не відкриває. Тоді англійський прошарок над Playwright не додає нічого, крім роботи: звичайний
test('користувач входить у систему')з гарною назвою — це вже документація, без витрат на парсинг Gherkin. - Сценарії імперативні (див. вище) — ви отримали крихкість UI-тестів плюс накладні витрати BDD і жодної читабельності натомість.
Просте правило: якщо прибрати Gherkin і ніхто поза командою автоматизації цього не помітить — він вам не потрібен.
Living documentation: коли документація справді жива
Найпринадніша обіцянка BDD — жива документація (living documentation). Логіка така: сценарії водночас і опис поведінки, і виконуваний тест. Якщо поведінка системи зміниться, а сценарій — ні, тест впаде. Отже, документація не може тихо застаріти: розбіжність між нею і кодом миттєво стає червоним білдом. Це радикально відрізняється від Confluence-сторінки, яку востаннє оновлювали два релізи тому.
Інструменти BDD генерують із прогону читабельні звіти — по суті специфікацію системи, де видно, які сценарії проходять (див. главу «Звітність» про звіт як продукт). Механіка привʼязки Gherkin-рядків до коду (step definitions, World, хуки в CucumberJS) — окрема тема інструментів, її розбирає відповідна глава розділу про інструменти автоматизації; тут важливий принцип, а не синтаксис степів.
Але «жива» вона лише за трьох умов, і кожну легко зламати:
- Сценарії декларативні й читабельні — інакше це «жива» стіна кліків, яку нехтоно читати.
- Її хтось реально читає — документація без читача мертва за визначенням.
- Сюїта зелена — набір, де половина сценаріїв у
@skipабо стабільно червоні, документує не систему, а занедбаність команди.
Living documentation — не безкоштовний наслідок Gherkin, а результат дисципліни. Той самий флакі-тест (глава «Флакі-тести») у BDD-обгортці шкодить подвійно: він і ламає gate, і підриває довіру до документа, який мав бути джерелом істини.
Типові помилки
- Виглядає як «ми впровадили BDD», а насправді — купили Cucumber і пишемо Gherkin постфактум наодинці. Без «трьох амігос» це не BDD, а дорожчий спосіб писати ті самі тести.
- Виглядає як читабельний сценарій, а насправді — імперативний переказ кліків: «вводить email, натискає кнопку». Бізнес його не читатиме, а ви отримали зайвий шар над крихким UI-тестом.
- Виглядає як жива документація, а насправді — 30% сценаріїв у
@ignoreі ніхто їх не відкриває місяцями. Документація, яку не читають і не тримають зеленою, мертва. - Виглядає як економія (один сценарій — багато кроків), а насправді — «сценарій-простирадло» з десятком When підряд: тестує все й нічого, падає з десяти причин, порушує атомарність.
- Виглядає як переваги Gherkin, а насправді — технічна команда пише сценарії сама для себе. Прибери прошарок — і
describe/itз гарними назвами дасть ту саму документацію дешевше. - Виглядає як повторне використання, а насправді — надто узагальнені кроки-«швейцарський ніж» на кшталт «When я натискаю "X"», з яких складають будь-що. Це не BDD-словник домену, а прихований imperative через чорний хід.
Підсумок
- BDD — це практика співпраці навколо прикладів поведінки; Gherkin і Cucumber — лише інструменти запису. Цінність народжується в розмові, а не у feature-файлі.
- Given–When–Then = Arrange–Act–Assert у прозі: Given — стан, When — одна дія, Then — перевірка; асертам не місце в Given, діям — у Then.
- Declarative (намір) перемагає imperative (кліки): стабільніший до змін UI, читабельний для бізнесу, ховає «як» у кроки коду.
- Gherkin окупається лише за реального нетехнічного читача й живої практики «трьох амігос»; для технічної команди, що пише для себе, це податок понад звичайні тести.
- Living documentation жива тільки поки сценарії декларативні, зелені й хтось їх читає; інакше це мертвий текст із накладними витратами.
Що питають на співбесіді
- «Що таке BDD?» Інтерв'юер перевіряє, чи не зводите ви BDD до інструмента. Сильна відповідь починається з «це практика співпраці, розмова про приклади поведінки до коду», і лише потім згадує Gherkin як формат запису.
- «Навіщо Given–When–Then, чим це краще за звичайний тест?» Дивляться, чи бачите ви звʼязок з AAA і читабельність для нетехнічного читача, а не просто «так прийнято».
- «Imperative vs declarative сценарій — у чому різниця й що краще?» Класика для middle. Очікують приклад обох і аргумент про стабільність та аудиторію, а не догму «declarative завжди».
- «Коли ви НЕ радите BDD?» Найпоказовіше питання: зрілий кандидат чесно каже, що для суто технічної команди без нетехнічних читачів Gherkin — накладні витрати. Незрілий вважає BDD універсальним добром.
- «Що таке living documentation і чому вона часто не працює?» Дивляться на розуміння умов: декларативність, зелена сюїта, реальний читач; і на чесність про типовий провал.
Джерела
- ISTQB Certified Tester Foundation Level (CTFL) 4.0 Syllabus — розділ про test-first підходи до розробки (TDD, ATDD, BDD).
- Dan North. Introducing BDD — першоджерело терміна: https://dannorth.net/blog/introducing-bdd/
- Martin Fowler. GivenWhenThen — розбір структури сценарію: https://martinfowler.com/bliki/GivenWhenThen.html
- Cucumber — Gherkin Reference (офіційна специфікація синтаксису): https://cucumber.io/docs/gherkin/reference/
Що таке BDD і чому неправильно зводити його до Gherkin?
BDD (Behavior-Driven Development, розробка через поведінку) — це передусім спосіб командної співпраці, а не набір ключових слів у файлі. Суть у тому, що бізнес, розробка й тестування разом розбирають майбутню фічу на конкретних прикладах поведінки ще до написання коду, і з цього народжується спільне розуміння. Gherkin, Cucumber, feature-файли — лише інструменти, які допомагають зафіксувати домовленість, але не створюють її. Тому відповідь «BDD — це коли пишемо тести на Gherkin» на співбесіді одразу видає слабкого кандидата: він переплутав практику з форматом запису. Головна цінність виникає в розмові про приклади, а текстовий сценарій — це вже її побічний продукт. Якщо команда пропустила обговорення й просто нагенерувала сценаріїв «щоб було модно», вона заплатила за інструмент, не отримавши головного.
Звідки взялося BDD і яку проблему TDD воно намагалося розвʼязати?
BDD виросло з TDD (Test-Driven Development) у середині 2000-х, коли Ден Норт (Dan North) помітив, що слово «тест» збиває новачків з пантелику. Люди застрягали на питанні «що і як тестувати», замість того щоб думати про очікувану поведінку системи. Ідея була в тому, щоб описувати не тести, а поведінку — прикладами й людською мовою, зрозумілою і бізнесу. Це зсунуло фокус з перевірки готового коду на прояснення вимог до його написання. Практичний наслідок: BDD природно тягне команду до розмови про приклади на ранньому етапі, коли непорозуміння ще дешево виправити.
Що таке «три амігос» і навіщо цей ритуал?
«Три амігос» (three amigos) — це зустріч трьох ролей навколо конкретної історії: представника бізнесу (product owner чи аналітик), розробника й тестувальника. Кожен приносить свій кут зору: бізнес знає, чого від фічі очікують, розробник — що реально можна збудувати, тестувальник — де це зламається й про які граничні ситуації всі забули. Мета зустрічі — не написати сценарії, а вирівняти розуміння й виловити суперечності у вимогах до того, як вони потраплять у код. Продукт розмови — спільне бачення поведінки; записані сценарії лише фіксують результат. Саме тут, а не у feature-файлі, створюється основна цінність BDD, тому пропустити цю розмову означає викинути головне.
Що таке example mapping і чим корисний його «стос питань»?
Example mapping (Метт Вінн, Matt Wynne) — це структурована техніка тієї самої розмови «трьох амігос». Беруть історію, виписують правила (rules), під кожне правило підбирають конкретні приклади (examples), а все незрозуміле складають в окремий стос запитань (questions). Найцінніше тут — саме той стос питань: він показує діри у вимогах наочно, ще до написання жодного рядка коду. Тобто зустріч окупається навіть тоді, коли не всі приклади розписані, — бо команда виявила, чого вона насправді не знає. Це і є та рання ловитва непорозумінь, заради якої BDD існує.
Як Given–When–Then співвідноситься з Arrange–Act–Assert?
Це та сама тришарова структура тесту, тільки в прозі. Given описує контекст і стан світу до події — це Arrange, підготовка. When — це подія чи дія, що запускає поведінку, і в ідеалі вона одна — це Act. Then — очікуваний спостережуваний результат — це Assert, перевірка. Практичний наслідок цієї відповідності — правило, яке ловлять на код-рев'ю: перевіркам не місце у Given, а натисканням кнопок і зміні стану — у Then. Один сценарій описує одну поведінку, а не ланцюжок з десяти дій «за компанію». Якщо кандидат бачить цей звʼязок, він розуміє, чому Gherkin структуровано саме так, а не просто «бо так прийнято».
Для чого потрібні Background і Scenario Outline?
Background виносить спільний для всіх сценаріїв контекст в одне місце, щоб не повторювати той самий Given у кожному сценарії — наприклад, «користувач залогінений». Scenario Outline розвʼязує іншу задачу: коли одну й ту саму поведінку треба перевірити на різних наборах даних, її записують один раз із плейсхолдерами, а самі дані виносять у таблицю Examples. По суті це data-driven тест засобами Gherkin: рядки таблиці стають окремими прогонами сценарію. Обидва механізми — про усунення дублювання, щоб сценарії лишалися читабельними. Плутати їх не варто: Background про спільну передумову, Outline про параметризацію.
У чому різниця між Gherkin і Cucumber?
Це різні шари, які часто змішують. Gherkin — це синтаксис і майже-природна мова: ключові слова Given/When/Then, структура feature-файлу, правила його оформлення. Cucumber (а також SpecFlow, Behave, вбудований BDD у CodeceptJS) — це інструмент, який цю мову виконує: парсить рядки, звʼязує їх зі step-функціями, ганяє сценарії як тести. Практичний наслідок: Given–When–Then можна вживати взагалі без жодного інструмента — наприклад, як формат критеріїв приймання (acceptance criteria) прямо в тікеті Jira. Тобто мова існує окремо від рушія, і формулювання критеріїв через GWT не зобовʼязує вас тягнути Cucumber у проєкт.
Чим імперативний сценарій відрізняється від декларативного і що краще?
Імперативний (imperative) сценарій описує кроки інтерфейсу: «вводить email у поле, вводить пароль, натискає кнопку». Декларативний (declarative) описує намір: «користувач входить у систему», а «як саме» ховається у визначенні кроку (step definition). Різниця не косметична, а вирішальна: імперативний сценарій крихкий — досить перейменувати поле чи змінити верстку, і доводиться редагувати той самий рядок, який нібито призначений для очей бізнесу; до того ж він нечитабельний для нетехнічного читача й фактично дублює page object у прозі. Декларативний стабільний до змін UI (правиться лише код кроку, не сценарій) і читається як вимога. Тому за замовчуванням орієнтир — декларативно, але без догми: у feature-файлі мова бізнесу й наміри, а вся механіка кліків і локаторів живе нижче, у коді кроків.
Чи буває сценарій «занадто декларативним»?
Так, і це друга крайність, про яку забувають. Якщо намір узагальнити до «When усе працює / Then все добре», сценарій читається красиво, але не перевіряє нічого конкретного — його тестова цінність нульова. Декларативність має ховати деталі реалізації, а не саму суть перевірки. Правильний баланс — сценарій навколо одного наміру домену, де результат конкретний, але не розписаний по кроках: не «вводить у поле email» і не «все ок», а щось на кшталт «потрапляє у свій профіль». Тобто читабельність не повинна коштувати визначеності: якщо зі сценарію не зрозуміло, що саме він гарантує, він марний незалежно від того, наскільки гарно звучить.
Який технічний оверхед додає Gherkin порівняно зі звичайним тестом?
Gherkin додає шар непрямування (indirection): feature-файл сам по собі не запускається — за кожним рядком має стояти функція-крок, яка розбирає параметри, і весь цей glue-код доводиться супроводжувати. Виходить довший ланцюжок: feature-файл → step definitions → page object чи API-клієнт → застосунок, і кожна стрілка — місце, де привʼязка може зламатися. Дебаг теж болючіший: коли червоніє крок «він входить у систему», причину доводиться діставати крізь кілька шарів замість того, щоб прочитати її одразу в тілі тесту. Звичайний Playwright-тест починається одразу з рівня step-логіки, тобто має на шар менше. Це не робить Gherkin поганим, але означає, що за нього треба платити, і платити варто лише коли є за що.
За яких умов Gherkin виправдовує свою ціну?
Головна умова одна — є реальний нетехнічний читач: продакт, аналітик, комплаєнс чи замовник справді відкривають сценарії або беруть участь у їх написанні. Друга — розмова відбувається насправді: команда практикує «три амігос» чи example mapping, і сценарії є підсумком спільного обговорення, а не витвором AQA поодинці. Третя — формат Given–When–Then закріплений у критеріях готовності історії як спільний контракт, а не осідає лише в тестовому репозиторії. Коли ці умови виконані, англомовний шар над тестами перетворюється на живий міст між бізнесом і кодом. Якщо жодна не виконується — ви несете витрати без вигоди.
Коли Gherkin стає чистим податком і як це розпізнати?
Коли інженерна команда автоматизації складає сценарії винятково для власного вжитку, а жоден колега без технічного бекграунду до них не зазирає, — надбудова над Playwright лише плодить роботу. У такому разі звичайний test('користувач входить у систему') з осмисленою назвою сам собою документує поведінку, і платити за парсинг та glue-код немає за що. Другий симптом податку — імперативні сценарії: до крихкості UI-тестів ви додали накладні витрати BDD, а читабельності натомість не здобули. Проста перевірка: подумки приберіть Gherkin — якщо цього не помітить ніхто, крім самих автоматизаторів, шар зайвий. Зрілий кандидат на співбесіді чесно назве цей випадок, а незрілий вважає BDD добром на всі випадки життя.
Що таке living documentation і за яких умов вона перестає працювати?
Жива документація (living documentation) стоїть на думці, що той самий сценарій є одночасно й описом поведінки, й виконуваним тестом: змінилася система без відповідної правки сценарію — тест червоніє, і невідповідність одразу стає видимою в білді. Через це документація не старіє тихцем, як Confluence-сторінка, до якої не торкалися два релізи. Але «живість» тримається на трьох стовпах, і кожен нескладно вибити: сценарії мусять лишатися декларативними й читабельними, їх має хтось справді відкривати, а сюїта — світитися зеленим. Коли третина сценаріїв висить у @skip чи хронічно падає, набір документує вже не продукт, а те, що команда махнула на нього рукою. Тому жива документація не падає з неба разом із Gherkin — вона тримається на дисципліні, і про це чесніше говорити прямо.
Чому флакі-тест у BDD-обгортці шкідливіший за звичайний?
Флакі-тест (flaky) — той, що падає й проходить на однакових умовах без змін коду — у BDD шкодить подвійно. По-перше, він робить те саме, що й будь-де: ламає gate, змушує перезапускати білд, підриває довіру до сюїти. По-друге — і це вже специфіка BDD — він руйнує довіру до сценарію, що мав слугувати джерелом істини. Якщо сценарій-документація то червоний, то зелений без причини, читач перестає вірити не лише тесту, а й самому опису поведінки. Тобто в BDD флакі б'є не тільки по інженерії, а й по головній обіцянці — живій документації. Тому в BDD-проєкті боротьба з флаком важить ще більше, ніж у звичайній сюїті.
Що не так зі «сценарієм-простирадлом» і надто узагальненими кроками?
«Сценарій-простирадло» — це коли в один сценарій ліплять десяток When підряд, намагаючись «заощадити». Виглядає як економія, а насправді перевіряє одразу все й через те по суті нічого: причин для падіння в нього десяток, атомарність зламана, і з червоного прогону не видно, що саме відмовило. Інший бік тієї ж хвороби — надміру універсальні кроки-«швейцарський ніж» типу «When я тисну на "X"», з яких можна зібрати геть будь-що. Це не доменний словник, а той самий imperative, який пробрався з чорного ходу: під виглядом кроку ви знову описуєте кліки, лише винесли їх у параметр. Здоровий орієнтир — один сценарій на один бізнес-намір і кроки, що говорять термінами домену, а не елементами інтерфейсу.
Як би ти пояснив на співбесіді, коли НЕ радиш впроваджувати BDD?
Я б почав з того, що BDD — не універсальне добро, а інструмент з конкретною умовою окупності: реальний нетехнічний читач і жива практика розмов. Якщо команда суто технічна, пише тести сама для себе й ніхто ззовні їх не відкриває, Gherkin додає glue-код, ускладнює дебаг і нічого не дає натомість — тут describe/it з осмисленими назвами дешевше й чесніше. Так само я б застеріг від «BDD постфактум», коли Cucumber купили, а розмови «трьох амігос» немає: це просто дорожчий спосіб писати ті самі тести. Здатність назвати межу застосовності — саме те, що інтерв'юер хоче почути, бо вона відрізняє людину з досвідом від того, хто вивчив синтаксис. Догма «declarative завжди» чи «BDD усюди» — червоний прапор незрілості.
Три кейси, у яких видно межу між обіцянкою BDD і реальністю: переписування крихкого імперативного сценарію на декларативний зі step-кодом, таблиця рішень «чи потрібен вам Gherkin взагалі», і міні-розбір історії через example mapping — де сам процес ловить діру у вимогах раніше за будь-який тест.
Кейс 1. Один сценарій, два світи: imperative → declarative
Прийшла історія «користувач логіниться». Перший AQA написав сценарій «як бачить», тобто через кроки інтерфейсу:
Feature: Автентифікація
Scenario: Логін (імперативно)
Given користувач на сторінці "/login"
When він вводить "user@test.io" у поле "email"
And вводить "Qwerty123" у поле "password"
And натискає кнопку "Увійти"
Then він бачить заголовок "Мій профіль"
Читається це не як вимога, а як інструкція до кліків. Тепер уявіть, що дизайнер перейменував поле email на login і замінив кнопку на іконку. Падає сам текст сценарію — той, що нібито мав читати продакт. Виходить найгірше з двох світів: крихкість UI-тесту плюс англомовний шар, який нікому не допомагає. По суті цей feature-файл дублює page object, тільки в прозі.
Той самий намір декларативно:
Feature: Автентифікація
Scenario: Логін (декларативно)
Given зареєстрований користувач
When він входить у систему
Then він потрапляє у свій профіль
Механіка кліків нікуди не зникла — вона переїхала на рівень нижче, у визначення кроків (step definitions), де їй і місце. Приклад на CodeceptJS:
import { Given, When, Then } from 'codeceptjs';
Given('зареєстрований користувач', async () => {
// стан готуємо через API, а не кліками — швидко й стабільно
const user = await api.createUser({ email: unique('user'), password: 'Qwerty123' });
currentUser = user;
});
When('він входить у систему', async ({ I }) => {
// уся крихкість локаторів схована тут; сценарій про неї не знає
I.amOnPage('/login');
I.fillField('email', currentUser.email);
I.fillField('password', currentUser.password);
I.click('Увійти');
});
Then('він потрапляє у свій профіль', ({ I }) => {
I.see('Мій профіль');
});
Що змінилося і чому це важливо:
- Перейменування поля тепер зачіпає лише крок
When, а не сценарій. Текст, який читає бізнес, переживає редизайн форми — правиться тільки код. - Сценарій читається як вимога. «Користувач входить у систему» зрозуміло продакту; «вводить у поле email» — ні.
- Given готує стан через API, а не через UI. Це та сама дисципліна, що й Arrange у звичайному тесті: передумову створюємо найдешевшим шляхом, а перевіряємо — саме поведінку.
- Балансу теж треба тримати. Якби Then звучав «Then усе добре», сценарій став би красивим і безкорисним. «Потрапляє у профіль» — конкретний, але не покроковий результат.
Кейс 2. Таблиця рішень: Gherkin окупається чи це податок?
Найчастіша помилка — впроваджувати Gherkin за замовчуванням, «бо BDD це добре». Насправді рішення зводиться до кількох чесних питань про вашу конкретну команду. Ось орієнтир замість здогадок:
| Ситуація | Нетехнічний читач справді читає сценарії? | Є розмова (три амігос / example mapping)? | Вердикт |
|---|---|---|---|
| Продакт бере участь у написанні критеріїв, комплаєнс переглядає сценарії | Так | Так | Gherkin окупається — є за що платити |
| AQA-команда пише сценарії сама, показує їх лише собі | Ні | Ні | Податок: describe/it з гарними назвами дешевше |
| Cucumber купили «щоб було по-BDD», сценарії пишуть постфактум | Ні | Ні | Податок + ілюзія практики; це не BDD |
| Критерії приймання у форматі GWT в Jira, автотести окремо звичайні | Так (у тікеті) | Частково | GWT як контракт — так; окремий Gherkin-рушій — не обовʼязково |
Як цим користуватися:
- Ключова колонка — читач. Якщо жоден нетехнічний колега ніколи не відкриє feature-файл, англомовний шар над Playwright не додає нічого, крім роботи. Це головна умова, не «модно/немодно».
- Розмова без інструмента цінніша за інструмент без розмови. Рядок 3 — класична пастка: заплатили повну ціну Cucumber, а вирівняного розуміння не отримали, бо обговорення не було.
- GWT можна відірвати від рушія. Рядок 4 показує компроміс: формулювати критерії приймання через Given–When–Then корисно навіть тоді, коли самі тести лишаються звичайними. Мова існує окремо від Cucumber.
- Проста фінальна перевірка. Подумки приберіть Gherkin зі свого проєкту. Якщо цього не помітить ніхто, крім самих автоматизаторів, — шар зайвий.
Кейс 3. Example mapping: як розмова ловить баг раніше за тест
Історія в беклозі звучить оптимістично: «Користувач може повернути замовлення й отримати гроші назад». Виглядає зрозуміло — доки команда не сідає за example mapping і не починає виписувати правила з прикладами. Кольорові картки тут умовні; важлива структура.
Rules (правила):
- Повернення доступне протягом 14 днів після доставки.
- Гроші повертаються тим самим способом, яким платили.
Examples (приклади під правила):
- Доставлено 10 днів тому, оплата карткою → повернення дозволене, гроші на картку.
- Доставлено 20 днів тому → повернення заборонене, показуємо причину.
Questions (стос запитань — те, чого ніхто не знає):
- А якщо товар оплатили бонусами, які вже згоріли, — куди повертати гроші?
- 14 днів рахуються від доставки чи від оформлення?
- Що з частковим поверненням, коли в замовленні кілька товарів?
Ось у чому суть кейсу: третє питання про бонуси не має відповіді ні в тікеті, ні в голові продакта — його виявили не тести, а сама розмова. Якби команда стартувала одразу з написання Gherkin постфактум, ця діра поїхала б у код, і її знайшли б у продакшені, а не за столом переговорів.
Коли на питання є відповіді, приклади перетворюються на сценарії — і природно декларативні, бо народилися з мови домену, а не з кліків:
Feature: Повернення замовлення
Scenario: Повернення в межах вікна повертає гроші тим самим способом
Given замовлення оплачене карткою й доставлене 10 днів тому
When користувач оформлює повернення
Then повернення підтверджене
And гроші повертаються на картку
Scenario Outline: Доступність повернення залежить від строку
Given замовлення доставлене "<днів>" днів тому
When користувач відкриває форму повернення
Then система показує "<результат>"
Examples:
| днів | результат |
| 10 | повернення доступне |
| 20 | строк повернення минув |
Що тут працює на нас:
- Стос питань окупив зустріч сам собою. Навіть якщо частину прикладів не встигли розписати, команда вже знає, чого не знає, — і це найдешевша точка виправити вимогу.
- Сценарії вийшли декларативними без спеціальних зусиль. Вони говорять термінами домену («оформлює повернення»), бо джерело — розмова про поведінку, а не запис кліків.
- Scenario Outline прибрав дублювання. Два майже однакові сценарії з різним строком стали одним параметризованим — це та сама ідея, що й data-driven тест.
- Без кроку example mapping усе це не спрацювало б. Feature-файл — лише запис домовленості; якби домовленості (і питання про бонуси) не було, гарний Gherkin просто акуратно зафіксував би неповну вимогу.
BDD як практика, а не інструмент
- Можу пояснити, що BDD — це співпраця навколо прикладів поведінки (Gherkin/Cucumber — лише спосіб її зафіксувати), і чому «пишемо тести на Gherkin» — слабка відповідь.
- Розумію, що головна цінність народжується в розмові, а feature-файл — її побічний артефакт.
- Знаю, звідки виросло BDD (з TDD, Ден Норт) і навіщо прибирали слово «тест».
Розмова: три амігос і example mapping
- Можу назвати три ролі в «трьох амігос» і що кожна привносить (бізнес — що треба, розробник — що можливо, тестувальник — що піде не так), і що продукт зустрічі — спільне розуміння, а не сценарії.
- Знаю, як влаштований example mapping (rules → examples → questions), і чому «стос питань» окупає зустріч ще до написання коду.
Анатомія сценарію: Given–When–Then
- Знаю призначення Given (контекст), When (одна дія), Then (спостережуваний результат).
- Можу показати відповідність GWT ↔ Arrange–Act–Assert і вивести з неї правило рев'ю: без асертів у Given, без дій у Then.
- Розумію, для чого Background (спільна передумова) і Scenario Outline з Examples (параметризація, data-driven), і знаю різницю між Gherkin (мова) і Cucumber (інструмент виконання) — GWT можна писати як критерії приймання без будь-якого інструмента.
Imperative проти declarative
- Можу навести один і той самий сценарій імперативно й декларативно та пояснити різницю.
- Знаю, чому імперативний сценарій крихкий і нечитабельний для бізнесу (дублює page object у прозі), а декларативний стабільніший: зміна UI зачіпає лише step definition.
- Можу пояснити пастку «занадто декларативно»: «все працює / все добре» нічого не перевіряє.
Ціна Gherkin: коли окупається, коли податок
- Знаю, який оверхед додає Gherkin: шар непрямування, glue-код, важчий дебаг через кілька рівнів.
- Можу назвати три умови окупності: реальний нетехнічний читач, жива практика розмов, GWT у критеріях готовності.
- Розумію тест «прибери Gherkin — чи хтось поза командою автоматизації помітить?» і можу чесно назвати випадок, коли НЕ раджу BDD (технічна команда пише для себе).
Living documentation
- Розумію, чому «жива» документація не може тихо застаріти (розбіжність = червоний білд).
- Знаю три умови її «живості»: декларативність, реальний читач, зелена сюїта.
- Можу пояснити, чому флакі-тест у BDD шкодить подвійно — ламає gate і підриває довіру до документа.
Типові пастки
- Розпізнаю «BDD постфактум»: Cucumber купили, розмови немає — це дорожчі ті самі тести.
- Розпізнаю «сценарій-простирадло» з десятком When і розумію, чому він порушує атомарність.
- Розпізнаю кроки-«швейцарський ніж» («When я натискаю X») як прихований imperative через чорний хід.
Що таке BDD за своєю суттю?
Питання
BDD — це передусім про що?