Автоматизація в процесі розробки: shift-left і ownership
Зміст
Автотести на проєкті є, але пишуться «колись потім» і вічно відстають від фіч. Володіє ними одна людина — і коли вона у відпустці, червону не чинить ніхто. Половина тестів «іноді падає», тож команда звикла ретраїти прогін, поки не позеленіє. Формально автоматизація є; фактично вона нічого не гарантує. Ця глава — про два питання, які вирішують, працює автоматизація чи лише імітує роботу: коли писати тести (shift-left) і хто за них відповідає (ownership).
Це поглиблена глава про процес, а не про код, і розрахована на senior-рівень. Якщо ви тільки вчитеся писати автотести, її можна пропустити при першому проході й повернутися, коли постане питання «як вбудувати тести в роботу команди». Тут — єдиний повний виклад shift-left і володіння тестами на сайті; інші глави розділу посилаються сюди. Механіка самого і quality gates докладно розібрана в розділі про Git і CI/CD — у цій главі ми дивимося на них з боку автоматизації.
Shift-left: тестувати раніше, а не «наприкінці»
Класична модель роботи: спочатку розробники пишуть код, потім він «перекидається через стіну» в тестування, і аж наприкінці спринту (а то й релізного циклу) QA починає шукати баги. Проблема — у ціні дефекту. Баг, спійманий на етапі вимог, коштує виправити копійки; той самий баг у проді — на порядки дорожче: перевипуск, , інцидент, репутація. Це один із семи принципів тестування — раннє тестування економить (early testing). Розділ «Основи тестування» розкриває його докладно.
Shift-left () — це зсув перевірок уліво по таймлайну розробки, ближче до моменту, коли дефект створюється. У контексті автоматизації це означає дуже конкретну річ: тест пишеться разом із кодом фічі, у тому ж pull request, а не окремою задачею «покрити автотестами» через два спринти. Петля фідбеку (feedback loop) стискається з тижнів до хвилин — розробник дізнається, що зламав, ще до рев'ю.
Важливо: shift-left ширший за автоматизацію. Він охоплює й рев'ю вимог (ловимо неоднозначність до написання коду), і (лінтери, типізація), і тест-дизайн на етапі уточнення історії. Але саме в автоматизації він найвідчутніший — через ідею self-testing code (код, що сам себе перевіряє): будь-який автоматично проганяє свій набір тестів і сам каже, справний він чи ні.
Головна пастка тут — плутати shift-left з «тестувати все і одразу вручну на ранній стадії». Це не про більше ручної роботи раніше. Це про дешеві автоматичні повторювані перевірки, вбудовані в момент, коли дефект коштує найменше.
Хто пише автотести: три моделі володіння
Питання «хто пише автотести» — не про посади в штатному розписі, а про відповідальність (ownership). Від відповіді залежить, чи будуть тести жити разом із продуктом, чи перетворяться на занедбаний цвинтар, який усі бояться чіпати.
- Окрема AQA-команда пише всі тести. Розробники кидають фічу, автоматизатори наздоганяють її тестами. Наслідки: тести структурно відстають від коду; розробники не почуваються відповідальними за зелену сюїту; знання про фічу й знання про її тест живуть у різних головах. Класична сегрегація, що народжує сирітські тести.
- Розподіл за рівнями піраміди. Розробники володіють unit- та (вони ближче за всіх до внутрішнього коду), AQA/SDET — API- та e2e-рівнем. Розумний компроміс, який спирається на природу рівнів (див. главу «Піраміда тестування»).
- Спільне володіння (whole-team approach). Тест — частина визначення «готово» для фічі; він лежить у тому ж PR, що й код; полагодити червоний тест — обовʼязок того, хто його зламав, а не абстрактної «команди тестування». За якість відповідає вся команда, а не окремий відділ контролю.
| Модель | Швидкість фідбеку | Ризик сирітських тестів | Хто чинить червоне |
|---|---|---|---|
| Окрема AQA-команда | низька | високий | автоматизатори |
| Розподіл за рівнями | середня | середній | автор рівня |
| Спільне володіння | висока | низький | автор зміни |
Whole-team approach — усталений термін з Agile-тестування. Він не скасовує спеціалізацію (глибокі e2e-сценарії й тестову архітектуру все одно тягне AQA/SDET), але прибирає головну хворобу сегрегації: коли ніхто не почувається власником червоного білда, він просто лишається червоним. Піраміда підказує природний розподіл: unit-тести живуть найближче до коду, тож їх логічно писати тим, хто цей код написав; що вище рівень, то більша роль автоматизаторів.
Тести в Definition of Done і PR-чеках
Найкраща стратегія володіння розсиплеться, якщо «написати тест» лишається доброю волею. Тому shift-left тримається на двох операційних гачках.
Definition of Done (DoD). Фіча не вважається завершеною, поки на неї немає тестів відповідного рівня. Це рядок у командному DoD (поняття з Agile, див. розділ «Основи тестування»), а не усна домовленість. Логіка проста: якщо тест не входить у визначення «готово», його завжди можна відкласти на «потім» — а «потім» на практиці означає «ніколи», бо наступна фіча вже горить.
PR-чеки (required status checks). Технічне втілення DoD у системі контролю версій. Через branch protection репозиторій налаштовують так, що злити гілку не можна, поки обовʼязкові перевірки не стануть зеленими: лінт, перевірка типів, unit-тести, вузький . Гейт стоїть саме там, де дефект найдешевший — до потрапляння в основну гілку. Механіку PR і захисту гілок докладно розбирає розділ про Git і CI/CD.
Ці два гачки й перетворюють shift-left з гасла на процес: тест зʼявляється разом із кодом, бо інакше зміна фізично не доїде до main.
Довіра до сюїти: один флакі руйнує gate
Гейт має цінність рівно доти, доки червоне означає реальну проблему. Це негласний контракт між сюїтою і командою. Один стабільно-нестабільний (flaky) тест цей контракт ламає: команда бачить червоне, знизує плечима, ретраїть прогін — і він зеленіє сам собою. Одного разу спрацювало, другого, третього. Далі настає (normalization of deviance): «червоне — це нормально, просто клікни retry». І в той день, коли червоним стане справжній регрес, його теж ретраять у забуття. Один терпимий знецінює всю сюїту — не тому, що ламає один сценарій, а тому, що вчить команду не вірити гейту.
Термін тут не наш і не з тестування: він прийшов із досліджень організаційної безпеки, і ми його позичаємо — джерело, на яке ми спираємося, описує охорону здоровʼя, а поняттям завдячує соціологині Даяні Вон (Diane Vaughan). Механізм там сформульований так: «Over time, even egregious violations of standards of practice may become "normalized"», і такі відхилення тримаються роками, «despite the importance of the standards at issue». Дві сили названі поіменно. Інституціоналізація: новачок бачить відхилення в авторитетних колег і читає його як норму організації — «explains those behaviors as organizationally normative». Раціоналізація: «Rationalization enables system operators to convince themselves that their deviances are not only legitimate, but acceptable and perhaps even necessary». А найпоширеніше виправдання ви чули у своїй команді дослівно: «Rule, or standards, deviators often interpret rule compliance as irrational and a drag on productivity» — тобто «гейт нас гальмує». Чому дрібне терпіти небезпечно, теж сказано: катастрофам передують «long incubation periods, typified by rule violations, discrepant events that accumulated unnoticed».
Звідси — дисципліна зеленого білда: зелений стан за замовчуванням, червоний — стоп-сигнал номер один. Хто зламав білд, той його чинить або відкочує зміну; не «полагоджу завтра». не терплять як фон, а лікують або виносять у , щоб вони не блокували чужі , доки їх не полагодять. Повна таксономія причин, діагностика й політика команди — у главі «Флакі-тести»; тут важливий лише висновок: довіра до сюїти — не мʼяка цінність, а того, що гейт узагалі має сенс. Її фундамент закладається ще на рівні окремого тесту — незалежного й детермінованого (див. главу «Анатомія автотесту»).
Розкладка прогонів: PR, nightly, реліз
Не всі тести мають бігти на кожен пуш. Тут працює компроміс між швидкістю фідбеку і повнотою : чим ширший набір, тим довший прогін, а довгий прогін на кожен PR зупиняє команду. Тому сюїту розкладають по стадіях.
- PR-прогін — швидкий і блокувальний. Лінт, перевірка типів, unit-тести, вузький смоук найкритичніших шляхів. Ціль — хвилини, не десятки хвилин, бо саме він стоїть між розробником і мерджем.
- Nightly — повна регресія: e2e на всіх браузерах, довгі сценарії, крос-конфігурації. Іде вночі, довго, і зазвичай не блокує мердж, а дає команді ранковий звіт про стан продукту. Швидкість тут забезпечує паралелізація (див. главу «Паралелізація»), а розбір нічних падінь — окрема дисципліна (див. главу «Звітність»).
- Перед релізом — повний прогін плюс ручні й дослідницькі перевірки; його результат входить у рішення про готовність до релізу.
Quality gate () — це автоматичний критерій, який блокує просування зміни далі пайплайном: не пройшов — не мерджиш або не . Що саме зробити блокувальним — інженерне рішення з наслідками. Наприклад, повільні й історично флакі e2e часто виносять з блокувальних PR-чеків у nightly, лишаючи на PR тільки швидкий надійний смоук. А покриття (coverage) як гейт — палиця з двома кінцями: жорсткий поріг на цифру породжує тести без , написані заради метрики, а не заради перевірки.
Ця розкладка й політика quality gates — окрема велика тема; її канонічний виклад — у розділі про Git і CI/CD (стратегія якості в пайплайні). Тут ми зафіксували лише погляд автоматизатора: один і той самий набір тестів обслуговує різні стадії з різними вимогами до швидкості й до права блокувати.
На рівні коду розкладка спирається на теги: критичні сценарії позначають, і PR ганяє лише їх, а nightly — усе.
// смоук-сценарії позначаємо тегом
test('логін відкриває дашборд @smoke', async ({ page }) => {
// ...
});
// на PR: npx playwright test --grep @smoke
// вночі: npx playwright test
Типові помилки
- Виглядає як «у нас є автоматизація», а насправді тести пишуться окремою задачею через кілька спринтів після фічі й вічно відстають — shift-left не сталося, гейта на дешевій стадії немає.
- Виглядає як «гейт працює, бо червоне блокує мердж», а насправді половина падінь — флакі, команда ретраїть прогін не дивлячись, і справжній регрес пройде тим самим шляхом у забуття.
- Виглядає як «e2e на кожен PR — це максимальна якість», а насправді 40-хвилинний прогін на кожен пуш зупиняє команду, і люди починають шукати способи мерджити в обхід — швидкість фідбеку вбита.
- Виглядає як «розробники не хочуть писати тести, це робота QA», а насправді unit-тест без доступу до внутрішнього коду й контексту напише лише його автор — сегрегація народжує сирітські тести й дублікати замість покриття.
- Виглядає як «100% coverage як гейт — це якість», а насправді гейт на покриття женуть цифрою, і зʼявляються тести без жодного асерту, які нічого не перевіряють.
Підсумок
- Shift-left — це не «більше ручного тестування раніше», а дешеві автоматичні перевірки в момент створення коду: тест живе в тому ж PR, що й фіча.
- Володіння тестами вирішує їхню долю; спільне володіння (whole-team) перемагає модель «окремий відділ пише тести пост-фактум».
- Тест у Definition of Done і в обовʼязковому PR-чеку — єдиний надійний спосіб не відкласти його на «потім, тобто ніколи».
- Гейт має цінність рівно доти, доки червоне означає реальну проблему; один терпимий флакі знецінює всю сюїту.
- Розкладка прогонів — це компроміс швидкість/покриття: смоук блокує PR за хвилини, повна регресія йде nightly, релізний прогін годує рішення про реліз.
Можливі питання
- «Що таке shift-left?» — чекають не гасло, а механізм: раніше = дешевше, тест разом із кодом, коротка петля фідбеку; плюс приклад із власної практики. Відповідь «тестувати на початку проєкту» без пояснення ціни дефекту — слабка.
- «Хто має писати автотести — розробники чи AQA?» — перевіряють, чи розумієте спільне володіння й піраміду. Сильний кандидат не рубає «звісно AQA», а розводить рівні: unit — ближче до розробника, e2e — до автоматизатора, відповідальність — спільна.
- «Тест іноді падає в CI, а локально зелений — що робиш?» — дивляться, чи не запропонуєте «додати retry» першим рухом. Чекають діагностику причини й розуміння, що терпимий флакі отруює весь гейт.
- «Що ганяти на кожен PR, а що — вночі?» — перевіряють відчуття компромісу швидкість/покриття і що таке quality gate; сильна відповідь називає смоук на PR і повну регресію в nightly з поясненням чому.
- «Чи має падіння e2e блокувати мердж?» — єдиної правильної відповіді немає; інтервʼюер дивиться на аргументацію: стабільність сюїти, критичність шляху, час прогону, ціна помилково заблокованого мерджу.
Джерела
Shift-left: тестувати раніше, а не «наприкінці»
- ISTQB® CTFL Syllabus v4.0.1 — §2.1.5 і принцип 3: shift-left — інша назва принципу раннього тестування, а не окрема практика; названо пʼять практик зсуву, і поруч — два застереження, які найчастіше губляться: зсув уліво не означає нехтувати пізніми стадіями, і він коштує дорожче на початку, а ще потребує згоди стейкхолдерів.
- Martin Fowler — SelfTestingCode — критерій, який робить ранній фідбек можливим: одна команда запускає тести, і зеленому результату можна довіряти; позиція джерела різка — нетривіальний код без тестів вважається зламаним.
- Martin Fowler — Continuous Integration — чому без цього не обійтися: семантичні конфлікти система контролю версій не ловить, і компілятор теж не завжди.
Хто пише автотести: три моделі володіння
- ISTQB® CTAL-TAE Syllabus v2.0 — §3.1: мати фреймворк автоматизації на кожному рівні тестування — «possible and recommended», а силосів між розробниками й тестувальниками має власну назву цілі — in-sprint automation.
- ISTQB® CTFL Syllabus v4.0.1 — §2.1.4: CI сприяє зсуву уліво, заохочуючи розробників подавати якісний код разом із компонентними тестами й статичним аналізом; водночас навіть за високого рівня автоматизації мануальне тестування з погляду користувача лишається потрібним.
Тести в Definition of Done і PR-чеках
- Martin Fowler — Continuous Integration — дисципліна, з якої й виріс гейт: самотестований білд і правило не лишати білд червоним.
- ISTQB® CTFL Syllabus v4.0.1 — §2.1.5: серед пʼяти названих практик зсуву прямо стоїть «писати тест-кейси до коду» й ганяти код у тестовому гарнесі під час реалізації — це і є DoD у формулюванні канону.
Довіра до сюїти: один флакі руйнує gate
- John Banja — The normalization of deviance in healthcare delivery — механізм, за яким терпимий флакі вбиває гейт, названий поіменно: «Over time, even egregious violations of standards of practice may become "normalized"», а найпоширеніше виправдання — що правило заважає продуктивності. Галузь джерела — медицина, перенос на CI-гейт наш (
trust: secondary, dec-0049). - Martin Fowler — Continuous Integration — протилежна дисципліна в першоджерелі: червоний білд лагодиться негайно, інакше сигнал перестає бути сигналом.
- Martin Fowler — SelfTestingCode — умова довіри сформульована як критерій: зеленому результату можна вірити щодо суттєвих дефектів.
Розкладка прогонів: PR, nightly, реліз
- ISTQB® CTFL Syllabus v4.0.1 — §2.1.4: серед вигід DevOps названо швидкий фідбек про якість коду й менший регресії завдяки масштабу автоматизованої регресії; ризики теж названі через
must— пайплайн треба визначити й побудувати, інструменти впровадити й підтримувати.
Що таке shift-left простими словами?
Shift-left — це зсунути перевірки вліво по таймлайну розробки, ближче до моменту, де дефект народжується, замість того щоб ловити його наприкінці спринту чи в проді. Причина суто економічна: баг, спійманий на етапі вимог чи одразу після написання коду, коштує копійки, а той самий баг у продакшені тягне за собою перевипуск, , інцидент і репутаційні збитки. Для автоматизації це означає дуже конкретну річ — тест народжується разом із кодом фічі, у тому ж pull request, а не окремою задачею «покрити автотестами» через два спринти. Петля фідбеку стискається з тижнів до хвилин: розробник дізнається, що зламав, ще до код-рев'ю. Слабка відповідь на співбесіді — «тестувати на початку проєкту» без згадки про ціну дефекту й коротку петлю фідбеку.
Shift-left — це про більше ручного тестування на ранній стадії?
Ні, і це головна пастка в розумінні терміна. Shift-left — не про те, щоб раніше й більше клікати руками, а про дешеві автоматичні повторювані перевірки, вбудовані туди, де дефект коштує найменше. Ручний прогін усього й одразу на ранній стадії просто розтягує ту саму дорогу роботу, тільки лівіше. Суть shift-left у зворотному: перекласти ранню перевірку на машину, яка проганяє її на кожен пуш за секунди. Тому коли кандидат каже «ми почали тестувати руками з першого тижня» — це ще не shift-left, а лише інша розкладка ручної праці.
Чи вичерпується shift-left автоматизацією?
Ні, він ширший. Shift-left охоплює й рев'ю вимог, де неоднозначність ловлять ще до написання коду, і (лінтери, типізація), і тест-дизайн на етапі уточнення історії. Просто в автоматизації він найвідчутніший, бо там працює ідея коду, що сам себе перевіряє: будь-який автоматично проганяє свій набір тестів і сам каже, справний він чи ні. Тобто автоматизація — найяскравіша, але не єдина форма . Сильний кандидат згадає й нетестові прояви: чим раніше вимога уточнена, тим менше зайвого коду доведеться потім переписувати.
Що таке self-testing code і чому він важливий для shift-left?
Self-testing code (код, що сам себе перевіряє) — це властивість кодової бази, за якої разом із кодом лежить набір автотестів, а будь-який білд автоматично їх проганяє й сам повідомляє, справний він чи зламаний. Без цього shift-left лишається гаслом: немає автоматичного вердикту — немає й швидкого фідбеку. Механізм простий: тести їдуть у тому ж репозиторії, що й код, і запускаються на кожен білд без ручної команди. Практичний наслідок — розробник не мусить памʼятати «а треба ще перевірити», бо білд сам червоніє на регресі. Це фундамент, на якому тримається self-testing build і вся дисципліна безперервної інтеграції.
Хто має писати автотести — розробники чи AQA?
Питання не про посади, а про відповідальність (ownership), і сильна відповідь не рубає «звісно AQA». Природний розподіл підказує піраміда: unit- та живуть найближче до внутрішнього коду, тож їх логічно писати тим, хто цей код написав — розробникам; API- та e2e-рівень ближчий до автоматизаторів (AQA/SDET). А відповідальність за зелений білд — спільна: полагодити червоний тест мусить той, хто його зламав, а не абстрактна «команда тестування». Модель, де окрема AQA-команда наздоганяє чужі фічі тестами, структурно програє: тести відстають, розробники не почуваються власниками , а знання про фічу й про її тест живуть у різних головах. Тому правильна рамка відповіді — розвести рівні й підкреслити спільну відповідальність.
Які є моделі володіння тестами і чим вони відрізняються?
Їх три. Перша — окрема AQA-команда пише всі тести: розробники кидають фічу, автоматизатори наздоганяють; наслідок — тести відстають, ніхто з розробників не власник зеленого білда, народжуються сирітські тести. Друга — розподіл за рівнями піраміди: розробники володіють unit/інтеграцією, AQA/SDET — API/e2e; розумний компроміс, що спирається на природу рівнів. Третя — спільне володіння (whole-team approach): тест входить у визначення «готово», лежить у тому ж PR, що й код, а червоне чинить автор зміни. Ключові осі порівняння — швидкість фідбеку (від низької до високої), сирітських тестів (від високого до низького) і хто відповідає за червоний білд. Whole-team дає найшвидший фідбек і найменший ризик сирітських тестів, бо власником якості стає вся команда.
Що таке whole-team approach і що він насправді змінює?
Whole-team approach — усталений термін з Agile-тестування: за якість продукту відповідає вся команда, а не окремий відділ контролю. Він не скасовує спеціалізацію — глибокі e2e-сценарії й тестову архітектуру все одно тягне AQA/SDET, — але лікує головну хворобу сегрегації. Хвороба ця в тому, що коли ніхто не почувається власником червоного білда, він просто лишається червоним. У whole-team тест — частина Definition of Done фічі, він у тому ж pull request, що й код, і зламаний тест чинить той, хто його зламав. Практичний наслідок: сюїта перестає бути «чужою» для розробників і не перетворюється на занедбаний цвинтар, який усі бояться чіпати.
Звідки беруться сирітські тести?
Сирітський тест — це тест, за який ніхто не почувається відповідальним, тому його ніхто не лагодить, не оновлює й боїться чіпати. Народжує їх сегрегація: коли окрема AQA-команда пише тести пост-фактум, знання про фічу лишається в розробника, а тест — у автоматизатора, і жоден із них не власник результату. Розробник не писав цей тест і не розуміє його; автоматизатор не писав фічу й не встигає за її змінами. Наслідок — тест структурно відстає від коду, дублює інші перевірки або тихо гниє в червоному стані. Лікування системне, а не косметичне: перенести володіння ближче до автора коду (whole-team або розподіл за рівнями), щоб у кожного тесту був живий власник.
Навіщо вносити тести в Definition of Done?
Бо без цього «написати тест» лишається доброю волею, а добра воля програє наступній фічі, яка вже горить. Definition of Done (визначення «готово») — це командна угода, за якою фіча не вважається завершеною, поки на неї немає тестів відповідного рівня; це рядок у DoD, а не усна домовленість. Логіка проста: якщо тест не входить у «готово», його завжди можна відкласти на «потім», а «потім» на практиці означає «ніколи». Внесення тесту в DoD робить його невідкладним — фіча просто не закривається без нього. Разом із обовʼязковим PR-чеком це перетворює shift-left із гасла на процес.
Що таке required status checks і як branch protection тримає shift-left?
Required status checks (обовʼязкові перевірки статусу) — це технічне втілення Definition of Done у системі контролю версій. Через branch protection () репозиторій налаштовують так, що злити гілку в основну не можна, поки обовʼязкові перевірки не позеленіли: лінт, перевірка типів, unit-тести, вузький . Гейт стоїть саме там, де дефект найдешевший — до потрапляння коду в main. Ключова властивість — його не обійти домовленістю: якщо перевірка червона, кнопка заблокована фізично. Саме тому DoD плюс PR-чек — єдина надійна пара, що не дає відкласти тест на «колись»: зміна просто не доїде до основної гілки без нього.
Чому один флакі-тест здатен знецінити всю сюїту?
Гейт має цінність рівно доти, доки червоне означає реальну проблему — це негласний контракт між сюїтою і командою. Один стабільно-нестабільний (flaky) тест цей контракт ламає: команда бачить червоне, знизує плечима, ретраїть прогін — і він зеленіє сам собою. Одного разу спрацювало, другого, третього, і формується звичка не дивитися на падіння. Проблема не в тому, що ламає один сценарій, а в тому, що він вчить команду не вірити гейту взагалі. І в день, коли червоним стане справжній регрес, його теж ретраять у забуття тим самим рефлексом. Тому терпимий — це не косметичний дефект одного тесту, а підрив довіри до всієї сюїти.
Що таке нормалізація відхилень і до чого вона в тестах?
(normalization of deviance) — поняття не з тестування, а з досліджень організаційної безпеки (за ним стоїть робота Даяні Вон про катастрофу «Челленджера»), і ми його позичаємо. У формулюванні джерела: «Over time, even egregious violations of standards of practice may become "normalized"» — і тримаються такі відхилення роками. Тобто це поступове звикання команди до того, що раніше вважалося неприпустимим, доки воно не стане фоновою нормою. У тестах вона розгортається так: спершу червоне падіння — це стоп-сигнал, потім «та це знову той флакі, клікни retry», а далі «червоне — це нормально». Кожен успішний підкріплює звичку не сприймати падіння всерйоз. Небезпека в тому, що межа між «терпимим шумом» і «реальним регресом» стирається — команда ретраїть все підряд, не дивлячись. Джерело називає два двигуни цього процесу: інституціоналізацію (новачок вчиться відхиленню в авторитетних колег і читає його як норму) і раціоналізацію (команда переконує себе, що відхилення легітимне й навіть потрібне), а найчастіше виправдання — що правило заважає продуктивності. Саме тому дисципліна вимагає не терпіти флакі як фон, а лікувати його або виносити в , поки контракт «червоне = проблема» ще живий.
Тест іноді падає в CI, а локально зелений. Який твій перший рух?
Перший рух — не «додати retry», і саме це на співбесіді й перевіряють. Retry першим кроком лише ховає симптом і починає ту саму нормалізацію відхилень: тест червоніє, його автоматично ретраять, справжня причина лишається. Правильний перший рух — діагностика: відтворити падіння, подивитися, що відрізняє CI від локального прогону (паралелізм, стан даних, гонки, таймінги, rate limit, ізоляція контексту). Терпимий флакі отруює весь гейт, тому його треба або полагодити, або свідомо винести в карантин, щоб він не блокував чужі мерджі, доки причину не знайдено. Ключова думка відповіді: retry — це не рішення, а спосіб перестати бачити проблему.
Що таке дисципліна зеленого білда і хто чинить червоне?
Дисципліна зеленого білда означає, що зелений стан — це норма за замовчуванням, а червоний — стоп-сигнал номер один, а не фонове тло. Чинить червоне той, хто його зламав: або лагодить зміну, або відкочує її, і не «полагоджу завтра», а зараз, бо зламаний білд блокує всю команду. Флакі при цьому не терплять як данину природі — його або лікують, або виносять у карантин, щоб він не заважав чужим мерджам. Сенс дисципліни в тому, щоб зберегти контракт «червоне = реальна проблема»: варто раз дозволити білду постояти червоним «бо це не критично», і починається сповзання до нормалізації відхилень. Це радше культурна норма команди, ніж технічне налаштування.
Що ганяти на кожен PR, а що — вночі?
Тут працює компроміс швидкість проти повноти : чим ширший набір тестів, тим довший прогін, а довгий прогін на кожен PR зупиняє команду. Тому сюїту розкладають по стадіях. На PR — швидкий блокувальний набір: лінт, перевірка типів, unit-тести і вузький смоук найкритичніших шляхів; ціль тут хвилини, бо саме цей прогін стоїть між розробником і мерджем. Уночі (nightly) — повна регресія: e2e на всіх браузерах, довгі сценарії, крос-конфігурації; вона йде довго й зазвичай не блокує мердж, а дає команді ранковий звіт про стан продукту. Перед релізом — повний прогін плюс ручні й дослідницькі перевірки, результат яких входить у рішення про готовність. Сильна відповідь називає смоук на PR, повну регресію вночі й пояснює чому саме так.
Чому nightly зазвичай не блокує мердж?
Бо повна регресія довга й ширша, і якби вона блокувала кожен PR, команда стояла б годинами замість хвилин. Nightly радше грає роль ранкового звіту: вночі проганяється весь набір e2e на всіх конфігураціях, а вранці команда бачить, у якому стані продукт, і розбирає падіння окремою дисципліною . Швидкість тут забезпечує паралелізація, а не звуження набору. Блокувати мердж лишається швидкий надійний смоук на PR — там гейт має право зупиняти, бо він короткий і стабільний. Виносити повільні й історично флакі e2e з блокувальних PR-чеків у nightly — типове й розумне інженерне рішення: PR не гальмується, а покриття не втрачається, просто зсувається за часом.
Що таке quality gate?
Quality gate () — це автоматичний критерій, який блокує просування зміни далі : не пройшов — не мерджиш або не . Найтиповіший приклад — обовʼязкові PR-чеки: лінт, типи, unit, смоук мають бути зеленими, інакше кнопка мерджу заблокована. Головна властивість гейта — він має право зупиняти рух, тому те, що робити блокувальним, є інженерним рішенням із наслідками. Зробиш блокувальним повільний флакі e2e — команда буде стояти й ретраїти; лишиш надто мало — регрес просочиться. Гейт працює рівно доти, доки його вердикт вартий довіри: щойно червоне перестає означати реальну проблему, гейт втрачає сенс, навіть якщо технічно він на місці.
Чи має падіння e2e блокувати мердж?
Єдиної правильної відповіді тут немає, і саме на це дивиться інтервʼюер — на аргументацію, а не на «так» чи «ні». Зважувати треба кілька осей: стабільність сюїти (наскільки цей e2e надійний чи історично флакі), критичність шляху (це оформлення замовлення чи другорядний екран), час прогону (хвилини чи 40 хвилин на кожен пуш) і ціну помилково заблокованого мерджу. Часто розумний баланс — лишити на PR тільки швидкий надійний смоук найкритичніших шляхів, а повільні й флакі e2e винести в nightly, де вони дають звіт, а не блокують. Якщо ж e2e стабільний, короткий і покриває критичний шлях — його блокувальність виправдана. Слабка відповідь — категоричне «завжди блокувати» або «ніколи не блокувати» без аналізу компромісів.
Coverage як quality gate — чому це палиця з двома кінцями?
Бо жорсткий поріг на цифру покриття (coverage) оптимізує метрику, а не якість перевірок. Коли гейт вимагає умовних 90%, зʼявляються тести, написані заради відсотка, а не заради перевірки: код виконується, рядки «покриті», але немає або вони порожні. Формально гейт зелений, фактично ці тести нічого не гарантують — вони прогнали код і не перевірили результат. Тобто метрика показує, що код виконувався в тесті, але не те, що його поведінку хтось перевірив. Coverage корисний як орієнтир і сигнал про голі зони, але як жорсткий блокувальний гейт він частіше народжує імітацію тестування, ніж реальне покриття. Сильна відповідь розрізняє «покриття як індикатор» і «покриття як самоціль».
Як технічно розкласти сюїту по стадіях?
На рівні коду розкладка спирається на теги: критичні смоук-сценарії позначають тегом, і PR ганяє лише їх, а nightly — увесь набір. У Playwright це виглядає як позначка в назві тесту, наприклад @smoke, і різні команди запуску: npx playwright test --grep @smoke на PR і npx playwright test уночі. Так один і той самий набір тестів обслуговує різні стадії з різними вимогами до швидкості й до права блокувати. Перевага підходу — не треба тримати окремі копії тестів чи окремі проєкти: розкладка задається фільтром на прогоні. Головне — дисципліновано тегувати саме критичні швидкі шляхи як смоук, інакше PR-прогін або роздується, або пропустить важливе.
Три ситуації, у яких shift-left і ownership перестають бути теорією: «що робити блокувальним на PR, а що зсувати в nightly», розбір занедбаної з діагнозом по симптомах, і природна прив'язка до коду — теги, якими одна сюїта обслуговує дві стадії.
Кейс 1. Що ставити блокувальним на PR: таблиця рішень
Питання «чи має цей тест блокувати мердж» вирішується не гаслом, а зважуванням кількох осей: час прогону, стабільність, критичність шляху й ціна помилково заблокованого . Ось як типові набори лягають на стадії:
| Перевірка | Час | Стабільність | Стадія | Блокує мердж? |
|---|---|---|---|---|
| Лінт, перевірка типів | секунди | висока | PR | так |
| Unit-тести | секунди–хвилина | висока | PR | так |
| Смоук критичних шляхів (логін, оформлення замовлення) | хвилини | висока | PR | так |
| Повна e2e-регресія, усі браузери | десятки хвилин | середня | nightly | ні, дає звіт |
| Історично флакі e2e | будь-який | низька | nightly / карантин | ні |
| Релізна регресія + ручні перевірки | години | — | перед релізом | входить у рішення про реліз |
Що дивитися і чому:
- Блокувальним ставлять швидке й надійне. Гейт стоїть між розробником і мерджем, тому його ціль — хвилини. Лінт, типи, unit і вузький дають дешевий вердикт «не зламав очевидне» за той час, поки людина не встигла перемкнутися на іншу задачу.
- Повільне й широке зсувають у nightly. Повна на всіх конфігураціях довга; якби вона блокувала кожен пуш, команда стояла б годинами. Уночі вона встигає прогнатися й дає ранковий звіт, а не гальмує мердж.
- Історично e2e — не на PR. Тест із низькою стабільністю в блокувальному чеку не захищає, а руйнує довіру: команда звикає ретраїти його не дивлячись. Його місце — або nightly, доки причину не полагоджено.
- Coverage у цій таблиці навмисно немає як блокувального гейта. Жорсткий поріг на цифру породжує тести без , написані заради метрики. Покриття корисне як індикатор голих зон, але блокувати мердж «бо 89%, а треба 90%» — це оптимізація числа, а не якості.
Кейс 2. Занедбана сюїта: діагноз по симптомах
На проєкт приходить новий інженер і бачить класичну картину: автотести є, але фічі виходять раніше за тести; сюїта тижнями червона; половина падінь «іноді сама зеленіє після retry». Формально автоматизація є — фактично вона нічого не гарантує. Розбір іде по симптомах, а не по «перепишімо все».
Симптом 1: тести відстають від фіч на кілька спринтів. Це не лінь конкретної людини, а наслідок моделі володіння. Якщо тести пише окрема AQA-команда пост-фактум, вони структурно приречені відставати: розробник уже зробив фічу й пішов далі, автоматизатор наздоганяє. Лікування — зсунути володіння: unit/інтеграцію до авторів коду, тест у Definition of Done фічі, щоб вона не закривалася без нього.
Симптом 2: червоний ніхто не чинить, коли одна людина у відпустці. Це діагноз «немає власника зеленого». Поки за сюїту відповідає абстрактна «команда тестування», а не автор зміни, білд просто лишається червоним. Whole-team approach прибиває відповідальність до того, хто зламав: червоне чинить він, зараз, або відкочує зміну.
Симптом 3: «цей тест іноді падає, просто ретрай». Це вже у дії. Кожен retry підкріплює звичку не дивитися на падіння, і в день, коли червоним стане справжній регрес, його ретраять у забуття тим самим рефлексом. Тут не можна лишати як є: або лікують, або виносять у карантин, щоб він не блокував чужі мерджі й не отруював контракт «червоне = проблема».
Порядок дій, який випливає з діагнозу: спершу відновити довіру до гейта (карантин флакі, зелене за замовчуванням), паралельно перенести володіння ближче до авторів коду й закріпити тест у DoD та обовʼязкових PR-чеках. Переписувати тести гуртом — останнє, а не перше: без зміни процесу нова сюїта згниє так само.
Кейс 3. Одна сюїта, дві стадії: розкладка тегами
Розкладка «смоук на PR, усе вночі» тримається не на копіюванні тестів у різні проєкти, а на тегах: критичні швидкі шляхи позначають, і фільтр на прогоні вирішує, що бігти.
import { test, expect } from '@playwright/test';
// смоук — критичний шлях, позначаємо тегом; біжить і на PR, і вночі
test('логін відкриває дашборд @smoke', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('qa@example.com');
await page.getByLabel('Пароль').fill('secret');
await page.getByRole('button', { name: 'Увійти' }).click();
await expect(page.getByRole('heading', { name: 'Дашборд' })).toBeVisible();
});
// довгий крос-браузерний сценарій без тегу — тільки в nightly
test('експорт звіту в PDF на всіх ролях', async ({ page }) => {
// ...повільний e2e, що не має блокувати мердж
});
Запуск різниться лише фільтром:
# на PR: лише швидкий блокувальний смоук
npx playwright test --grep @smoke
# вночі: увесь набір, повна регресія
npx playwright test
Що дивитися і чому:
- Тег
@smokeживе в назві тесту, а стадію задає--grep. Одна й та сама сюїта обслуговує PR і nightly з різними вимогами до швидкості й права блокувати — без дублікатів і без окремих репозиторіїв. - Смоук-тегом позначають саме критичні швидкі шляхи. Якщо начепити
@smokeна повільний e2e, PR-прогін роздується й перестане бути хвилинним гейтом. Дисципліна тегування — частина розкладки, а не дрібниця. - прив'язані до ролі й лейбла, а не до крихких селекторів. Смоук на PR має бути надійним, бо він блокувальний: флакі-локатор у ньому одразу підриває довіру до гейта, з якої починається вся ця глава.
Shift-left
- Можу пояснити shift-left через ціну дефекту: чим раніше спійманий баг, тим дешевше, і саме тому перевірки зсувають вліво по таймлайну.
- Розумію, що для автоматизації shift-left означає тест у тому ж PR, що й код фічі (коротка петля фідбеку — розробник дізнається про поломку ще до код-рев'ю), а не окрему задачу через кілька спринтів.
- Не плутаю shift-left із «більше ручного тестування раніше» — це про дешеві автоматичні повторювані перевірки, а не про ранній ручний прогін.
- Розумію, що shift-left ширший за автоматизацію: рев'ю вимог, і тест-дизайн — теж .
- Можу пояснити self-testing code: сам проганяє свій набір тестів і сам каже, справний він чи ні.
Володіння тестами (ownership)
- Знаю три моделі володіння (окрема AQA-команда, розподіл за рівнями піраміди, спільне володіння) й осі порівняння: швидкість фідбеку, сирітських тестів, хто чинить червоний білд.
- Розумію, чому модель «окрема AQA пише все пост-фактум» народжує сирітські тести: знання про фічу й про її тест живуть у різних головах.
- Можу пояснити whole-team approach: за якість відповідає вся команда, червоне чинить автор зміни (спеціалізація лишається — глибокі e2e й тестову архітектуру тягне AQA/SDET).
- Розумію, як піраміда підказує розподіл: unit ближче до розробника, e2e — до автоматизатора.
Definition of Done і PR-чеки
- Можу пояснити, чому тест у Definition of Done — це рядок у DoD, а не усна домовленість: інакше його відкладуть на «потім», тобто ніколи.
- Знаю, що required status checks (PR-чеки) — технічне втілення DoD через branch protection: злити гілку не можна, поки перевірки червоні (лінт, типи, unit, ).
- Розумію, що DoD плюс обовʼязковий PR-чек — єдина надійна пара, яка не дає відкласти тест, бо зміна фізично не доїде до
main.
Довіра до сюїти й флакі
- Можу пояснити, чому один терпимий знецінює всю : гейт цінний, лише поки червоне = реальна проблема, а вчить команду не вірити гейту.
- Знаю, що таке (normalization of deviance), звідки поняття (організаційна безпека, не тестування) і як «клікни retry» перетворює червоне на фонову норму; можу назвати два двигуни — інституціоналізацію й раціоналізацію.
- Розумію дисципліну зеленого білда: зелене за замовчуванням, червоне чинить автор поломки зараз; флакі не терплять як фон — лікують або виносять у .
- На питання «тест іноді падає в CI» першим рухом даю діагностику причини, а не «додати retry».
Розкладка прогонів і quality gates
- Розумію компроміс швидкість проти : ширший набір = довший прогін, а довгий прогін на кожен PR зупиняє команду.
- Знаю розкладку по стадіях: смоук + unit блокують PR за хвилини, повна йде nightly (не блокує , дає ранковий звіт), релізний прогін годує рішення про реліз.
- Знаю, що таке quality gate: автоматичний критерій, що блокує просування зміни; повільні й історично флакі e2e часто виносять із PR-чеків у nightly.
- Можу пояснити, чому coverage як жорсткий гейт — палиця з двома кінцями: поріг на цифру народжує тести без .
Квіз
Перед стартом
- Питань: 13
- Поріг «зараховано»: ≥70% правильних відповідей.
- Результат впливає на прогрес; завалені питання підуть у чергу повторення.
- Квіз впливає на компліт теми: тема стає «пройдено», лише коли прочитано теорію І квіз складено на ≥70%.
Питання
Shift-left — що це одним реченням?