Покриття вимог і трасування
Зміст
«Ми протестували достатньо?» — питання, на яке доводиться відповідати перед кожним релізом. Відповідь «ну, ми багато тестували» не приймає ні менеджер, ні інтервʼюер. Аргументована відповідь завжди зводиться до покриття: скільки елементів із тих, що треба було перевірити, реально закрито тестами. І тут же перша пастка: «покриття 87%» без уточнення, чого саме 87%, — порожній звук. 87% вимог, рядків коду чи правил таблиці рішень — це три різні числа про три різні речі.
Ця глава — про те, як звʼязати вимоги з тестами так, щоб на «чи все покрито?» відповідала таблиця, а не інтуїція: види покриття, матриця трасування (RTM), пошук прогалин і тестів-сиріт, і як усе це живе в TMS та автотестах. Ланцюжком test basis → тестова умова → тест-кейс із глави про шлях від вимоги до перевірки ми досі рухалися лише вперед — від вимоги до кейсів. Тепер навчимося ходити ним в обидва боки.
Покриття — це завжди покриття «чогось»
Формула покриття одна: кількість елементів, зачеплених тестами, поділити на кількість усіх ідентифікованих елементів. Уся різниця між видами покриття — у тому, що вважати елементом і звідки брати їхній повний список.
| Вид покриття | База (звідки елементи) | Елемент покриття | На яке питання відповідає |
|---|---|---|---|
| Вимог | Специфікація, user story, критерії приймання | Вимога або окремий критерій | Чи перевірено все, що обіцяли користувачу |
| Коду | Вихідний код | Оператор, гілка, умова | Чи виконувався тестами весь написаний код |
| Ризиків | Матриця ризиків | Ідентифікований продуктовий ризик | Чи прикриті найнебезпечніші сценарії |
Ключове: це три незалежні осі, і одна не замінює іншу. Код може виконуватися тестом, який нічого по суті не перевіряє, — покриття коду зросте, покриття вимог ні. Вимога може бути взагалі не реалізована — покриття коду цього не покаже, бо неіснуючі рядки не входять у знаменник; а от у матриці вимог така діра світиться одразу. Тому «покриття вимог 100%, покриття коду 60%» — не суперечність, а нормальна картина: тести ходять по всіх вимогах, але частина коду (обробка помилок, службові гілки) ними не зачеплена.
Механіку покриття коду — statement, branch і чому 100% операторів не означає 100% гілок — розбираємо окремо в главі про білоскринькові техніки. Покриття ризиків спирається на матрицю «ймовірність × вплив» — це канонічна тема ризик-орієнтованого тестування в розділі про основи тестування; тут важливо лише, що ризик — така сама одиниця покриття, як вимога чи гілка коду.
Елементи покриття технік
Кожна техніка тест-дизайну з попередніх глав — це, по суті, машинка з виробництва елементів покриття (coverage items): вона бере вимогу і видає скінченний список того, що треба закрити тестами.
| Техніка | Елемент покриття | 100% означає |
|---|---|---|
| Класи еквівалентності | Клас (партиція) | Кожен клас зачеплено хоча б одним значенням |
| Граничні значення | Межа | Перевірено всі межі (2- або 3-точково) |
| Таблиці рішень | Правило (стовпець таблиці) | Кожне здійсненне правило має свій кейс |
| Переходи станів | Стан або перехід | Пройдено всі стани / всі переходи |
| Покриття коду | Оператор, гілка | Виконано весь код / усі гілки |
Саме тому «покрито на 100%» — незавершене речення, поки не названо техніку. 100% класів еквівалентності і 100% переходів станів для тієї самої фічі — різні набори тестів і різний рівень впевненості. Звідси й сильна відповідь на класичне «як зрозуміти, що тестів достатньо?»: обираю техніку під тип логіки, рахую її елементи покриття, показую, що всі закриті, — а решту добираю за ризиками. Як саме обирати техніку — тема глави про вибір і комбінування технік.
RTM: матриця, яка звʼязує вимоги з тестами
Матриця трасування вимог (requirements traceability matrix, RTM) — таблиця відповідності між вимогами і тестами, найпростіший робочий вигляд якої такий:
| Вимога | Тест-кейси | Останній прогін |
|---|---|---|
| REQ-101 Пароль 8–64 символи | TC-310, TC-311, TC-312 | passed |
| REQ-102 Блокування після 5 невдалих спроб | TC-315, TC-316 | TC-316 failed |
| REQ-103 Відновлення пароля через email | — | тестів немає |
Одна таблиця відповідає одразу на три питання: що покрито, що зламано (failed у TC-316 миттєво перекладається мовою бізнесу — «під загрозою блокування акаунтів») і де діра (REQ-103 узагалі без тестів). Без матриці кожне з цих питань — окреме розслідування.
Трасування (traceability) — ширше поняття, ніж таблиця «вимога ↔ кейс». Це здатність пройти весь ланцюжок робочих продуктів у два боки: вперед — від вимоги до її тестів і результатів, назад — від тесту чи дефекту до вимоги, яку він зачіпає. Таку властивість зазвичай називають двобічним трасуванням (bidirectional traceability).
Два практичні рішення при побудові:
- Гранулярність. Трасувати варто до окремого критерію приймання або тестової умови, а не до user story цілком. Story з вісьмома AC, до якої прилінковано один happy-path тест, у матриці виглядає «покритою» — і це найпоширеніший спосіб самообману. Формати AC та їхню роль розбирали у главі про сценарії використання.
- Дефекти теж у ланцюжку. Регресійний тест, написаний на баг, часто трасується не на вимогу, а на дефект. Якщо матриця бачить лише вимоги, такі тести виглядають сиротами — хоча прикривають реальні болючі місця.
Тепер про підтримку — і це важливіше за побудову. RTM, складена один раз, протухає в день першої зміни вимог. Живою матриця лишається за єдиної умови: звʼязки оновлюються в тому самому процесі, де змінюються вимоги і тести. Новий кейс без лінка на вимогу не проходить рев'ю; вимога змінилась — тікет не закривається, поки не переглянуті привʼязані тести. Excel-матриця, яку хтось «актуалізує щоквартально», цієї умови не витримує — тому на практиці трасування живе в TMS, де лінк ставиться за секунду в момент створення кейсу.
Пошук прогалин: неперевірені вимоги і тести-сироти
Двобічність трасування дає два протилежні типи знахідок.
Вимога без тестів (coverage gap) — найдорожча діра: дефект у непокритій вимозі знаходить не тестувальник, а користувач. Пошук механічний: фільтр «вимоги релізу без привʼязаних кейсів» — і список того, що треба або покрити, або свідомо, письмово прийняти як ризик. Саме «свідомо»: прогалина, про яку знають і яку прийняли, — це рішення; прогалина, про яку дізналися з продакшену, — провал процесу.
Тест-сирота (orphan test) — тест, не привʼязаний до жодної вимоги. Тут головне — не хапатися за кнопку «видалити». У сироти три типові причини, і лише одна з них — сміття:
- вимогу змінили або видалили, а тест лишився — кандидат на оновлення чи видалення;
- тест перевіряє недокументовану, але реальну поведінку — хтось колись знайшов баг чи мовчазне очікування користувачів і закрив його тестом; правильна дія — задокументувати вимогу і привʼязати, а не зносити перевірку;
- тест дублює наявний — ось це справді баласт.
Тому робота з сиротами починається з питання «що ти перевіряєш?», а не з чистки. Механічне видалення всіх сиріт — класичний спосіб знести регресійні перевірки багфіксів і отримати повторне відкриття старих дефектів.
Третя, найбільш недооцінена користь трасування — аналіз впливу (impact analysis). Вимога змінилася: backward-трасування за секунду відповідає, які тести застаріли і що треба прогнати, — замість «переглянемо всі 800 кейсів, раптом щось зачепило». Це щоденна робоча функція матриці; звіт про покриття — лише її побічний продукт.
Метрики покриття: користь і межі
Користь метрики покриття вимог — у трьох ролях:
- Критерій виходу. «Усі вимоги релізу покриті, критичні — пройдені» — вимірюваний рядок у тест-плані замість «тестування завершено, коли скінчився час».
- Прозорість. Менеджменту не цікаво «ми стараємось»; «94 зі 100 критеріїв закриті, ось список шести відкритих з ризиками» — мова, якою ухвалюють рішення про реліз.
- Аргумент при скороченні. Коли часу на повну регресію немає, матриця показує, що саме випадає з прогону і які вимоги лишаються без сітки, — скорочення стає керованим ризиком, а не лотереєю.
Тепер межі — і на співбесіді middle-рівня питають саме про них:
- Метрика бінарна. Вона бачить наявність звʼязку, а не силу перевірки. Вимога з одним поверховим happy-path тестом і вимога з двадцятьма тестами за класами і межами у звіті виглядають однаково: «покрито». Сто відсотків покриття вимог — це «на кожну вимогу є хоч щось», не більше.
- Метрика сліпа до невимовленого. Покриття вимог рахується від написаних вимог. Усе, чого в специфікації немає — неявні очікування, нефункціональні аспекти, поведінка на стиках фіч, — у знаменник не потрапляє. Система може пройти 100% вимог і бути непридатною: це помилкове уявлення про відсутність дефектів (absence-of-defects fallacy) із семи принципів тестування (розділ про основи тестування).
- Метрика-ціль псується. Щойно відсоток покриття стає KPI, він росте найдешевшим способом: вимоги дробляться на тривіальні, до них лінкуються аби-які тести. Число зелене, впевненості нуль. Покриття — діагностичний прилад для команди, а не показник продуктивності для звіту.
Трасування в TMS і звʼязка з автотестами
У TMS (TestRail, Zephyr, Xray тощо) трасування — це не окремий документ, а побічний продукт гігієни: кейс має поле звʼязку з вимогою (типово — тікет у Jira), дефект лінкується до кейсу й вимоги, а RTM і звіт покриття будуються автоматично як зріз цих лінків. Ручна Excel-матриця вмирає на першій сотні кейсів; у TMS вона оновлюється тим самим рухом, яким створюється кейс.
З автотестами є розрив: код живе в git, вимоги — у трекері. Стандартне рішення — ID вимоги в тегах або анотаціях тесту:
import { test, expect } from '@playwright/test';
test('акаунт блокується після пʼяти невдалих спроб входу',
{ tag: ['@REQ-102'] },
async ({ page }) => {
// кроки перевірки
});
Такий тег працює одразу на два боки:
- Трасування. Репортери TMS-інтеграцій читають теги і привʼязують результати прогону до кейсів та вимог — колонка «останній прогін» у матриці заповнюється без ручної праці.
- Фільтр запуску.
npx playwright test --grep "@REQ-102"— прогін усіх перевірок конкретної вимоги перед її релізом чи після зміни. Трасування перестає бути звітністю і стає інструментом запуску.
Правило гігієни те саме, що й для кейсів у TMS: тег вимоги додається в тому ж pull request, що й сам тест. Трасування, яке «допишемо потім», не доживає до потім.
Типові помилки
- Виглядає як «покриття вимог 100% — можна релізити», а насправді метрика каже лише, що на кожну вимогу є хоча б один тест. Вона мовчить і про якість цих тестів, і про все, чого у вимогах не написали.
- Виглядає як «RTM — документ, який складають наприкінці для звіту», а насправді головна функція матриці — щоденний impact analysis і пошук прогалин. Складена постфактум, вона протухла ще до того, як її відкрили.
- Виглядає як «тест без вимоги — сміття, видаляємо», а насправді сирота часто прикриває недокументовану вимогу або старий багфікс. Спершу зʼясуй, що він перевіряє, — потім вирішуй.
- Виглядає як «прилінкували тест до user story — покрито», а насправді story з вісьмома критеріями приймання формально «закрита» одним happy-path тестом. Трасувати треба до окремого критерію чи тестової умови.
- Виглядає як «покриття коду 85%, отже вимоги майже покриті», а насправді це різні осі: код може виконуватися без змістовних перевірок, а нереалізовану вимогу покриття коду не побачить узагалі.
Підсумок
- Покриття — це дріб «перевірені елементи / всі ідентифіковані елементи». Без назви бази (вимоги, код, ризики, елементи конкретної техніки) відсоток беззмістовний.
- Кожна техніка тест-дизайну постачає власні елементи покриття; вимоги, код і ризики — три незалежні осі, одна не замінює іншу.
- Цінність RTM — у двобічності: вперед вона знаходить неперевірені вимоги, назад — тести-сироти і відповідь на «що прогнати після зміни вимоги».
- Матриця жива, лише якщо звʼязки оновлюються в тому самому процесі, де змінюються вимоги й тести; актуалізація «раз на квартал» — це мертвий документ.
- Метрика покриття показує наявність звʼязку, а не силу перевірки; 100% — привід спитати «100% чого і наскільки глибоко», а не розслаблятися.
Що питають на співбесіді
- «Що таке RTM і навіщо вона?» Слабка відповідь зупиняється на «табличка вимоги-тести для звіту». Сильна називає двобічне трасування і щоденні функції: пошук прогалин, тести-сироти, impact analysis при зміні вимог.
- «Як зрозуміти, що тестів достатньо?» Інтервʼюер чекає структуру, а не «коли час скінчився»: елементи покриття обраних технік закриті, вимоги трасовані, залишкові прогалини названі і прийняті за ризиком.
- «Покриття вимог 100%, покриття коду 60% — як це можливо?» Перевірка, чи розумієш різні бази вимірювання. Бонус — зворотний приклад: високе покриття коду при дірявих вимогах.
- «Вимога змінилася — ваші дії?» Дивляться, чи згадаєш трасування як інструмент: backward-звʼязки дають список тестів на оновлення і прогін, без перегляду всього набору.
- «Як ви звʼязуєте автотести з вимогами?» Очікують практику: ID вимоги в тегах/анотаціях, TMS-інтеграція з результатами прогонів, тег як фільтр запуску. Плюс — правило «лінк у тому ж PR, що й тест».
Джерела
- ISTQB CTFL Syllabus v4.0.1 (PDF) — глава покриває розділ 1.4.4 «Traceability between the Test Basis and Testware»; елементи покриття кожної техніки названі в розділах 4.2–4.3 (огляд — 4.1 «Test Techniques Overview»).
- Глосарій ISTQB — канонічні означення: coverage, coverage item, traceability, traceability matrix.
- ISO/IEC/IEEE 29119-3:2021 «Software and systems engineering — Software testing — Part 3: Test documentation» — формальні вимоги до тестової документації, включно з трасуванням у тест-плані та звітності.
- Playwright: Annotations and tags — офіційна документація тегів і анотацій з прикладу вище, включно з фільтрацією через
--grep.
Що таке покриття тестами і як його рахують?
Покриття — це дріб: кількість елементів, зачеплених тестами, поділена на кількість усіх ідентифікованих елементів. Формула одна для всіх видів покриття; різниця лише в тому, що вважати елементом і звідки брати їхній повний список — вимоги зі специфікації, оператори й гілки з коду, ризики з матриці ризиків. Саме тому відсоток без назви бази — порожній звук: «покриття 87%» може означати 87% вимог, 87% рядків коду чи 87% правил таблиці рішень, і це три різні числа про три різні речі. Практичний наслідок: перш ніж називати відсоток у звіті, треба явно сказати, від чого він порахований.
Чим покриття вимог відрізняється від покриття коду?
Це дві незалежні осі вимірювання, і одна не замінює іншу. Покриття вимог рахується від специфікації та критеріїв приймання і відповідає на питання «чи перевірено все, що обіцяли користувачу»; покриття коду рахується від вихідного коду і показує, чи виконувався тестами весь написаний код. Код може виконуватися тестом, який нічого по суті не перевіряє, — покриття коду зросте, покриття вимог ні. А нереалізовану вимогу покриття коду не побачить узагалі: неіснуючі рядки не входять у знаменник, тоді як у матриці вимог така діра світиться одразу.
Що таке RTM і навіщо вона?
Матриця трасування вимог (requirements traceability matrix, RTM) — таблиця відповідності між вимогами і тестами, у мінімальному вигляді: вимога → привʼязані тест-кейси → результат останнього прогону. Одна таблиця відповідає одразу на три питання: що покрито, що зламано (failed тесту миттєво перекладається мовою бізнесу — «під загрозою блокування акаунтів») і де діра — вимоги взагалі без тестів. Слабка відповідь зупиняється на «табличка для звіту»; сильна називає щоденні функції: пошук прогалин, виявлення тестів-сиріт і аналіз впливу (impact analysis) при зміні вимог. Без матриці кожне з цих питань — окреме розслідування.
Що таке трасування і що означає «двобічне»?
Трасування (traceability) — здатність пройти ланцюжок робочих продуктів: вимога → тестові умови → тест-кейси → результати прогонів → дефекти. Двобічність (bidirectional traceability) означає, що ланцюжком можна ходити в обидва боки: вперед — від вимоги до її тестів і результатів, назад — від тесту чи дефекту до вимоги, яку він зачіпає. Кожен напрям дає свій тип знахідок: вперед матриця знаходить неперевірені вимоги, назад — тести-сироти і список тестів на прогін після зміни вимоги. Саме двобічність відрізняє живий інструмент від таблички, складеної для звіту.
Що таке елемент покриття і чому «покрито на 100%» — незавершене речення?
Елемент покриття (coverage item) — одиниця, від якої рахується знаменник дробу: клас еквівалентності, межа, правило таблиці рішень, стан чи перехід, оператор чи гілка коду. Кожна техніка тест-дизайну — по суті машинка з виробництва таких елементів: бере вимогу і видає скінченний список того, що треба закрити тестами. Тому «100%» без назви техніки нічого не каже: 100% класів еквівалентності і 100% переходів станів для тієї самої фічі — різні набори тестів і різний рівень впевненості. Сильний кандидат завжди уточнює: сто відсотків чого саме.
Покриття вимог 100%, а покриття коду 60% — як таке можливо?
Це не суперечність, а нормальна картина, бо бази вимірювання різні. Тести ходять по всіх вимогах — тому покриття вимог повне; але частина коду (обробка помилок, службові гілки, захисні перевірки) цими тестами не зачеплена — тому покриття коду нижче. Можливий і зворотний перекіс: високе покриття коду при дірявих вимогах — тести виконують майже весь код, але половина обіцяного користувачу не перевіряється по суті, або код узагалі не реалізує частину вимог. Висновок: дві метрики читаються разом, кожна ловить свої діри.
Як знайти вимоги без тестів і що з ними робити?
Пошук механічний: фільтр у TMS «вимоги релізу без привʼязаних кейсів» — це і є прогалини покриття (coverage gap). Це найдорожчий тип діри: дефект у непокритій вимозі знаходить не тестувальник, а користувач. Для кожної знахідки є рівно два легальні виходи: покрити тестами або свідомо, письмово прийняти як ризик. Ключове слово — «свідомо»: прогалина, про яку знають і яку прийняли, — це рішення; прогалина, про яку дізналися з продакшену, — провал процесу.
Що таке тест-сирота і чи треба його видаляти?
Тест-сирота (orphan test) — тест, не привʼязаний до жодної вимоги, і хапатися за кнопку «видалити» тут не можна. Причин три, і лише одна з них — сміття: вимогу змінили чи видалили, а тест лишився (кандидат на оновлення або видалення); тест перевіряє недокументовану, але реальну поведінку — хтось закрив тестом знайдений баг чи мовчазне очікування користувачів (правильна дія — задокументувати вимогу і привʼязати); тест дублює наявний (ось це справді баласт). Тому робота з сиротою починається з питання «що ти перевіряєш?», а не з чистки. Механічне видалення всіх сиріт — класичний спосіб знести регресійні перевірки багфіксів і отримати повторне відкриття старих дефектів.
До чого правильно трасувати тести — до user story чи до окремого критерію приймання?
До окремого критерію приймання або тестової умови, не до story цілком. Story з вісьмома критеріями, до якої прилінковано один happy-path тест, у матриці виглядає «покритою» — і це найпоширеніший спосіб самообману в трасуванні: формально зелено, реально сім критеріїв без перевірки. Гранулярність до критерію робить метрику чесною: видно, який саме критерій закритий, а який висить. Окремо варто памʼятати про дефекти в ланцюжку: регресійний тест, написаний на баг, трасується на дефект, а не на вимогу, — якщо матриця бачить лише вимоги, такі тести помилково виглядають сиротами.
Вимога змінилася. Ваші дії?
Перший інструмент — backward-трасування: за секунду воно дає список тестів, привʼязаних до цієї вимоги, тобто відповідь на «що застаріло і що треба прогнати» — замість «переглянемо всі 800 кейсів, раптом щось зачепило». Це і є аналіз впливу (impact analysis) — найбільш недооцінена, але щоденна функція матриці; звіт про покриття — лише її побічний продукт. Далі процесна гігієна: тікет зі зміною вимоги не закривається, поки привʼязані тести не переглянуті. Якщо тести тегувалися ID вимоги, туди ж додається прогін автотестів фільтром, наприклад npx playwright test --grep "@REQ-102".
Як зрозуміти, що тестів достатньо?
Інтервʼюер чекає структуру, а не «коли скінчився час». Сильна відповідь: обираю техніку тест-дизайну під тип логіки, рахую її елементи покриття (класи, межі, правила, переходи) і показую, що всі закриті; вимоги трасовані до критеріїв приймання, тож видно, що жодна не лишилася без перевірки; залишкові прогалини названі явно і прийняті за ризиком. Тобто «достатньо» — це не відчуття, а вимірюване твердження: усі ідентифіковані елементи покриття закриті, а те, що свідомо не закрито, зафіксовано як прийнятий ризик.
Покриття вимог 100% — можна релізити?
Сто відсотків — привід спитати «100% чого і наскільки глибоко», а не розслаблятися. Метрика має три межі. Вона бінарна: бачить наявність звʼязку, а не силу перевірки — вимога з одним поверховим happy-path тестом і вимога з двадцятьма тестами за класами і межами у звіті виглядають однаково. Вона сліпа до невимовленого: рахується від написаних вимог, а неявні очікування, нефункціональні аспекти й поведінка на стиках фіч у знаменник не потрапляють — система може пройти 100% вимог і бути непридатною, це помилкове уявлення про відсутність дефектів (absence-of-defects fallacy). І вона псується, щойно стає ціллю. Тому 100% покриття — необхідна, але не достатня умова релізу.
Що станеться, якщо зробити відсоток покриття KPI команди?
Метрика почне рости найдешевшим способом, а не найкориснішим: вимоги дробляться на тривіальні, до них лінкуються аби-які тести — число зелене, впевненості нуль. Це загальний ефект «метрика-ціль псується»: покриття — діагностичний прилад для команди (де діри, що прогнати, чим ризикуємо), а не показник продуктивності для звіту. Щойно за число починають преміювати чи карати, воно перестає вимірювати те, заради чого його рахували. Практичний висновок: у звіт менеджменту йде не голий відсоток, а список непокритого з ризиками — така форма маніпуляції піддається значно гірше.
Чому RTM в Excel протухає і де трасування живе на практиці?
Матриця жива за єдиної умови: звʼязки оновлюються в тому самому процесі, де змінюються вимоги і тести, — новий кейс без лінка на вимогу не проходить ревʼю, вимога змінилась — тікет не закривається без перегляду привʼязаних тестів. Excel-файл, який хтось «актуалізує щоквартально», цієї умови не витримує: він протухає в день першої зміни вимог і вмирає на першій сотні кейсів. Тому на практиці трасування живе в TMS (TestRail, Zephyr, Xray): кейс має поле звʼязку з вимогою (типово — тікет у Jira), дефект лінкується до кейсу й вимоги, а RTM і звіт покриття будуються автоматично як зріз цих лінків. Трасування там — побічний продукт гігієни, а не окремий документ, який треба «складати».
Як ви звʼязуєте автотести з вимогами?
Розрив у тому, що код живе в git, а вимоги — у трекері; стандартне рішення — ID вимоги в тегах або анотаціях тесту, у Playwright це tag: ['@REQ-102']. Тег працює одразу на два боки. Перший — трасування: репортери TMS-інтеграцій читають теги і привʼязують результати прогону до кейсів та вимог, колонка «останній прогін» у матриці заповнюється без ручної праці. Другий — фільтр запуску: npx playwright test --grep "@REQ-102" проганяє всі перевірки конкретної вимоги перед її релізом чи після зміни — трасування перестає бути звітністю і стає інструментом запуску. Правило гігієни: тег вимоги додається в тому ж pull request, що й сам тест, бо трасування «допишемо потім» не доживає до потім.
Три кейси з робочого життя трасування: читання RTM за годину до go/no-go (де діри і якою мовою про них казати), аудит тестів-сиріт через таблицю рішень замість кнопки «видалити» і звʼязка Playwright-тестів з вимогами тегами — з точковим прогоном після зміни вимоги.
Кейс 1. RTM перед релізом: що казати на go/no-go
Реліз фічі «вхід і блокування акаунта», до мітингу година. Питання менеджера буде одне: «ми протестували достатньо?». Замість «ми багато тестували» відкриваємо зріз матриці по вимогах релізу:
| Вимога | Тест-кейси | Останній прогін |
|---|---|---|
| REQ-101 Пароль 8–64 символи | TC-310, TC-311, TC-312 | passed |
| REQ-102 Блокування після 5 невдалих спроб | TC-315, TC-316 | TC-316 failed |
| REQ-103 Відновлення пароля через email | — | тестів немає |
| REQ-104 Story «Профіль користувача», 8 AC | TC-401 | passed |
Що дивитися і чому:
- REQ-102: failed одразу перекладається мовою бізнесу. Не «впав TC-316», а «під загрозою блокування акаунтів» — саме так рядок матриці стає аргументом на мітингу. Без матриці звʼязок «тест → вимога → наслідок для користувача» довелося б відновлювати розслідуванням.
- REQ-103 — прогалина покриття (coverage gap), найдорожчий тип діри. Дефект тут знайде не тестувальник, а користувач. Легальних виходів рівно два: покрити до релізу або свідомо, письмово прийняти як ризик. Прогалина, про яку дізналися з продакшену, — це вже провал процесу, а не рішення.
- REQ-104 виглядає зеленою — і це пастка гранулярності. Story з вісьмома критеріями приймання «закрита» одним happy-path тестом TC-401: формально покрито, реально сім критеріїв без перевірки. Правильна дія — перетрасувати до окремих AC, і тоді матриця чесно покаже 1 з 8.
- Форма відповіді менеджменту — не голий відсоток, а «стільки-то критеріїв закрито, ось список відкритих з ризиками». Список маніпуляції піддається значно гірше, ніж число.
Кейс 2. Аудит тестів-сиріт: таблиця рішень замість чистки
Фільтр у TMS «кейси без лінка на вимогу» видав 14 тестів. Спокуса — видалити всі разом і «почистити» проєкт. Правильний перший крок для кожного — питання «що ти перевіряєш?», і лише потім дія:
| Що зʼясували про тест | Діагноз | Дія |
|---|---|---|
| Вимогу, яку він перевіряв, видалили два спринти тому | Застарілий | Оновити під нову поведінку або видалити |
| Перевіряє експорт, якого немає в жодній вимозі, але користувачі ним живуть | Недокументована, але реальна поведінка | Задокументувати вимогу і привʼязати — не зносити перевірку |
| Написаний як регресія на BUG-77 після багфікса | Трасується на дефект, а не на вимогу | Лишити; навчити матрицю бачити дефекти в ланцюжку |
| Крок у крок повторює наявний TC-315 | Дублікат | Видалити — ось це справді баласт |
Що дивитися і чому:
- Сміття — лише один рядок із чотирьох. Механічне видалення всіх сиріт — класичний спосіб знести регресійні перевірки багфіксів і отримати повторне відкриття старих дефектів.
- Рядок із дефектом — не сирота, а дефект матриці. Якщо RTM бачить лише вимоги, регресійні тести на баги завжди виглядатимуть непривʼязаними, хоча прикривають найболючіші місця.
- Рядок із недокументованою поведінкою — знахідка, а не проблема. Хтось колись закрив тестом реальне очікування користувачів; аудит сиріт — шанс нарешті внести його у вимоги.
Кейс 3. Теги в Playwright: вимога змінилася — що прогнати
Код живе в git, вимоги — у трекері; місток між ними — ID вимоги в тегах тесту:
import { test, expect } from '@playwright/test';
test('акаунт блокується після пʼяти невдалих спроб входу',
{ tag: ['@REQ-102'] },
async ({ page }) => {
// кроки перевірки
});
Тепер REQ-102 змінилася: блокування після трьох спроб замість пʼяти. Backward-трасування в TMS дає список ручних кейсів на перегляд, а той самий тег у коді — точковий прогін автотестів вимоги:
npx playwright test --grep "@REQ-102"
Що дивитися і чому:
- Тег працює на два боки. Репортери TMS-інтеграцій читають теги і привʼязують результати прогону до кейсів та вимог — колонка «останній прогін» у матриці заповнюється без ручної праці. А
--grepперетворює трасування зі звітності на інструмент запуску. - Це і є impact analysis у щоденній роботі. Замість «переглянемо всі 800 кейсів, раптом щось зачепило» — секундний список того, що застаріло і що прогнати. Сам тест із прикладу після зміни вимоги впаде або застаріє — і саме тег показав, що його треба оновити.
- Правило гігієни: тег — у тому ж pull request, що й тест. Новий тест без лінка на вимогу не проходить ревʼю; трасування «допишемо потім» не доживає до потім.
Види покриття
- Знаю формулу покриття: зачеплені тестами елементи поділити на всі ідентифіковані — і що без назви бази («87% чого?») відсоток беззмістовний.
- Можу пояснити три незалежні осі покриття: вимог (специфікація, AC), коду (оператори, гілки), ризиків (матриця ризиків) — і чому одна не замінює іншу.
- Можу пояснити, як «покриття вимог 100%, коду 60%» співіснують без суперечності, і чому нереалізовану вимогу покриття коду не побачить (неіснуючі рядки не входять у знаменник).
Елементи покриття технік
- Знаю елемент покриття кожної техніки: клас еквівалентності, межа, правило таблиці рішень, стан/перехід, оператор/гілка коду.
- Розумію, чому «покрито на 100%» — незавершене речення, поки не названо техніку: 100% класів і 100% переходів — різні набори тестів і різна впевненість.
RTM і трасування
- Можу намалювати мінімальну RTM (вимога → тест-кейси → останній прогін) і назвати три питання, на які вона відповідає: що покрито, що зламано, де діра.
- Знаю, що таке двобічне трасування (bidirectional traceability): вперед — від вимоги до тестів і результатів, назад — від тесту чи дефекту до вимоги.
- Розумію, чому трасувати треба до окремого критерію приймання чи тестової умови, а не до user story цілком: story з вісьмома AC «покрита» одним happy-path — самообман.
- Памʼятаю, що регресійні тести на баги трасуються на дефект, а не на вимогу, — матриця «лише вимоги» помилково бачить їх сиротами.
- Знаю єдину умову живої матриці: звʼязки оновлюються в тому самому процесі, де змінюються вимоги і тести; «актуалізація щоквартально» — мертвий документ.
Прогалини, сироти, impact analysis
- Можу знайти прогалину покриття (coverage gap) фільтром «вимоги без привʼязаних кейсів» і знаю два легальні виходи: покрити або свідомо, письмово прийняти як ризик.
- Знаю три причини тесту-сироти: вимогу змінили/видалили, тест прикриває недокументовану поведінку, тест дублює наявний — і що сміття лише третя.
- Розумію, чому робота з сиротами починається з питання «що ти перевіряєш?»: механічне видалення зносить регресійні перевірки багфіксів.
- Можу пояснити аналіз впливу (impact analysis): backward-трасування за секунду дає список тестів на оновлення і прогін після зміни вимоги.
Метрики: користь і межі
- Знаю три ролі метрики покриття вимог: вимірюваний критерій виходу, прозорість для менеджменту, аргумент при скороченні регресії.
- Можу пояснити, чому метрика бінарна: бачить наявність звʼязку, а не силу перевірки — один happy-path і двадцять тестів за межами виглядають однаково «покрито».
- Розумію звʼязок зі 100% покриття і помилковим уявленням про відсутність дефектів (absence-of-defects fallacy): невимовлені очікування в знаменник не потрапляють.
- Знаю, що стається з покриттям-KPI: вимоги дробляться на тривіальні, лінкуються аби-які тести — число зелене, впевненості нуль.
TMS і автотести
- Розумію, чому на практиці трасування живе в TMS як побічний продукт гігієни (поле звʼязку з вимогою, автоматична RTM), а Excel вмирає на першій сотні кейсів.
- Знаю патерн звʼязки автотестів з вимогами: ID вимоги в тегах (
tag: ['@REQ-102']), TMS-репортери читають теги,--grep "@REQ-102"— фільтр запуску; тег додається в тому ж pull request, що й тест.
У звіті написано «покриття 87%». Чому це порожній звук без уточнення?
Питання
Формула покриття тестами — і головна пастка відсотка?