Рівні тестування
Зміст
«Назвіть рівні тестування» — одне з найчастіших питань на співбесіді trainee/junior QA, і провалюють його не через незнання назв. Назви якраз завчують усі: модульний, інтеграційний, системний, приймальний. Провалюють наступне питання — «а чим інтеграційне тестування відрізняється від системного?» — бо за назвами не стоїть розуміння, що саме перевіряється на кожному рівні і які дефекти там живуть.
У роботі це розуміння потрібне щодня, навіть якщо ти ніколи не напишеш жодного unit-тесту. Коли розробник каже «це покрито юнітами», ти маєш розуміти, що це означає для твого ручного чеклиста. Коли баг відтворюється лише на зв'язці двох сервісів — це підказка, на якому рівні його пропустили і кому його адресувати. Рівень — це система координат, у якій команда домовляється, хто за що відповідає.
Що таке рівень тестування
Рівень тестування (test level) — це група тестових активностей, організована навколо певного об'єкта тестування: окремий модуль, зв'язка модулів, система цілком або система в руках користувача. Кожен рівень має власну мету, власний тест-базис (документи, з яких виводяться перевірки) і власний типовий клас дефектів.
Класична модель — чотири рівні:
- Модульний (unit/component) — перевіряємо найменшу частину коду ізольовано.
- Інтеграційний (integration) — перевіряємо взаємодію між частинами.
- Системний (system) — перевіряємо систему цілком, очима користувача.
- Приймальний (acceptance) — перевіряємо готовність до впровадження.
Силабус ISTQB CTFL 4.0 виділяє п'ять рівнів: інтеграційний там розділено на компонентний інтеграційний (component integration — взаємодія модулів усередині системи) і системний інтеграційний (system integration — взаємодія вашої системи з іншими системами, наприклад із платіжним провайдером чи поштовим сервісом). На співбесіді достатньо чотирьох, але про цей поділ варто знати: питання «а як тестувати інтеграцію зі Stripe?» — це саме system integration.
Важлива межа: рівні — це не види. Функціональне, регресійне, смоук — це види тестування, і вони застосовні на будь-якому рівні: буває регресія на unit-рівні й регресія на системному. Детальніше — у главі «Види тестування: класифікація».
Модульне тестування — і навіщо воно мануальному QA
Модульне (unit) тестування перевіряє найменшу окрему частину коду — функцію, метод, клас — в ізоляції від решти системи. Пишуть і запускають такі тести зазвичай розробники, тим самим інструментарієм, що й сам код. Ізоляція означає: якщо функція розрахунку знижки викликає базу даних, у unit-тесті базу підмінять заглушкою — тест перевіряє логіку функції, а не роботу бази.
Мінімальний приклад мовою TypeScript:
import { test, expect } from '@playwright/test';
import { calculateDiscount } from '../src/pricing';
// Unit-тест: жодного браузера, жодної мережі — лише логіка функції
test('знижка 10% застосовується до замовлення від 1000 грн', () => {
expect(calculateDiscount(1000)).toBe(900);
});
test('знижка не застосовується до замовлення нижче порогу', () => {
expect(calculateDiscount(999)).toBe(999);
});
Такий тест виконується за мілісекунди, не потребує середовища і точно вказує на місце поломки: впав тест calculateDiscount — дефект у calculateDiscount. У цьому головна сила рівня: дешевизна і точна локалізація.
Навіщо це мануальному QA, який цих тестів не пише:
- Щоб не дублювати роботу. Якщо межі й крайові значення функції знижки покриті юнітами, ганяти руками двадцять комбінацій сум — марнування часу. Ручний фокус зміщується туди, куди юніти не дістають: інтеграція, UI, реальні дані.
- Щоб грамотно тріажити баги. «Знижка рахується неправильно» і «знижка рахується правильно, але не відображається» — дефекти різних рівнів, і адресувати їх треба по-різному.
- Щоб читати сигнали якості. Зелені юніти в pull request — мінімальна гігієна білда, який приїде до тебе на тестування. Червоні — привід не починати ручний прогін узагалі.
- Бо це перша сходинка до AQA. Піраміда тестування (розділ «Автоматизація») будується саме на розумінні, що дешевше ловити внизу.
Інтеграційне тестування: big bang, top-down, bottom-up
Кожен модуль окремо працює — це ще нічого не гарантує. Модуль А повертає суму в копійках, модуль Б очікує в гривнях; сервіс А шле дату як 2026-07-16, сервіс Б парсить американський формат. Інтеграційне тестування перевіряє взаємодію: контракти, формати даних, послідовності викликів, обробку помилок на стиках. Типові дефекти цього рівня не видно всередині жодного окремого модуля — вони живуть саме між ними.
Ключове питання інтеграції — в якому порядку збирати й перевіряти зв'язки. Класичні підходи:
| Підхід | Як збираємо | Ціна |
|---|---|---|
| Big bang | Усе разом за один раз, тестуємо готову зв'язку | Дефект шукаємо по всій системі одразу |
| Top-down | Від верхніх модулів до нижніх, нижні підмінюємо заглушками | Треба писати заглушки (stubs) |
| Bottom-up | Від нижніх модулів до верхніх, верхні імітуємо драйверами | Треба писати драйвери (drivers) |
Big bang — зібрати все і подивитися, що вийде. Приваблює відсутністю підготовчої роботи, але коли щось падає (а щось впаде), локалізувати дефект серед десятків одночасно з'єднаних модулів дорого й довго. Виправданий хіба для малих систем із кількох модулів.
Top-down починає з верхніх рівнів логіки (наприклад, з UI чи головного контролера). Нижні модулі, яких ще немає або які ще не перевірені, замінюють заглушками (stubs) — спрощеними імітаціями, що повертають заготовлені відповіді. Плюс: скелет системи і головні сценарії видно рано. Мінус: низькорівнева логіка (розрахунки, робота з даними) перевіряється останньою.
Bottom-up — навпаки: спочатку інтегрують і перевіряють нижні модулі, а виклики зверху імітують драйверами (drivers) — допоміжним кодом, який смикає модуль так, як смикав би відсутній верхній рівень. Критична низькорівнева логіка перевіряється першою, але працюючу систему цілком видно лише наприкінці.
На практиці підходи комбінують і рухаються інкрементно: інтегрувати по одному з'єднанню і перевіряти одразу — саме тому, що так дефект локалізується миттєво. У сучасних проєктах значна частина інтеграційних перевірок іде через API — тому тестувальнику потрібні HTTP і REST як робочі інструменти.
Системне тестування
Системне тестування перевіряє систему цілком — зібрану, розгорнуту, з реальними інтеграціями — на відповідність вимогам. Об'єкт тестування — поведінка продукту очима користувача: наскрізні сценарії, функціональні й нефункціональні вимоги, робота на середовищі, максимально наближеному до продакшену.
Це «домашній» рівень мануального тестувальника: більшість ручних тест-кейсів, чеклистів і регресійних прогонів живе саме тут. Виконує його зазвичай незалежна команда тестування — незалежна від авторів коду, бо свіже око без знання «як воно влаштоване всередині» знаходить те, повз що розробник пройде (він знає, як «треба» користуватись своїм кодом).
Типові дефекти рівня: наскрізний сценарій ламається на переході між кроками, система поводиться неправильно під реальними даними, конфігурація середовища відрізняється від очікуваної, нефункціональні вимоги (швидкість відповіді, зручність) не витримуються. Окремий клас знахідок — розбіжності між вимогами і реалізацією, яких не видно на нижніх рівнях, бо там тест-базисом був дизайн коду, а не вимоги до продукту.
Приймальне тестування: UAT, alpha, beta
Приймальне (acceptance) тестування відповідає на інше питання, ніж усі попередні рівні. Не «чи є дефекти?», а «чи готова система до впровадження і чи розв'язує вона задачу бізнесу?». Знайти багато багів на прийманні — погана новина: вони мали бути знайдені раніше.
Основні форми:
- UAT (user acceptance testing) — перевірка реальними користувачами або представниками замовника: чи можуть вони виконати свої бізнес-процеси в системі. Тест-базис — бізнес-вимоги та acceptance criteria. Типовий результат UAT — не баг-репорт, а рішення: приймаємо / приймаємо з умовами / не приймаємо.
- Операційне приймальне (operational acceptance) — перевірка готовності до експлуатації руками адміністраторів: бекапи й відновлення, моніторинг, встановлення та оновлення.
- Контрактне і регуляторне — відповідність контракту із замовником або вимогам регулятора (актуально для фінтеху, медицини, держсектору).
- Альфа-тестування (alpha) — потенційні користувачі тестують продукт на боці розробника: на його середовищі, під наглядом команди.
- Бета-тестування (beta) — зовнішні користувачі тестують продукт у себе: на власних пристроях, у власному оточенні, без нагляду. Класика для масових продуктів: бета ловить дефекти конфігурацій і сценаріїв, які неможливо відтворити в лабораторії.
Різниця alpha/beta — не в «ступені готовності білда», як часто відповідають на співбесіді, а в місці та контролі: альфа — у розробника під наглядом, бета — у користувачів у дикій природі.
Рівні у V-моделі
V-модель (детально — у главі «SDLC: моделі розробки ПЗ») — найнаочніший спосіб побачити, звідки рівні беруться. Ліва гілка — деталізація від бізнес-вимог до коду; права — рівні тестування, і кожен рівень дзеркалить відповідний етап лівої гілки: перевірки цього рівня плануються і виводяться саме з того документа.
Звідси два практичні висновки. Перший: тест-базис визначає рівень. Перевірку, виведену з бізнес-вимоги, безглуздо проганяти на unit-рівні — і навпаки. Другий: тести кожного рівня можна (і треба) проєктувати ще тоді, коли пишеться відповідний документ, — задовго до появи коду. Це і є раннє тестування з семи принципів: рев'ю вимог на лівій гілці дешевше за баг-репорт на правій.
Хто виконує на кожному рівні
| Рівень | Хто зазвичай виконує | Тест-базис |
|---|---|---|
| Модульний | Розробники | Детальний дизайн, код |
| Інтеграційний | Розробники і тестувальники | Архітектура, контракти API |
| Системний | Незалежна команда тестування | Вимоги до системи |
| Приймальний | Користувачі, замовник, бізнес; ops-команда для операційного | Бізнес-вимоги, acceptance criteria |
«Зазвичай» тут важливе слово: розподіл залежить від команди і моделі розробки. В Agile-командах межі розмиваються — тестувальник бере участь у рев'ю unit-покриття, розробник ганяє системні сценарії, UAT проводять щоспринту на демо. Але логіка відповідальності зберігається: чим нижчий рівень, тим ближче виконавець до коду; чим вищий — тим ближче до бізнесу.
Типові помилки
- Виглядає як «інтеграційне тестування — це коли перевіряємо, що всі модулі працюють», а насправді воно перевіряє взаємодію, а не модулі повторно. Якщо на інтеграційному рівні ти тестуєш логіку всередині модуля — ти дублюєш unit-рівень і пропускаєш стики.
- Виглядає як «смоук і регресія — це теж рівні», а насправді це види/типи тестування, які існують на кожному рівні. Плутанина «рівень vs вид» — найчастіший спосіб завалити це питання на співбесіді.
- Виглядає як «UAT — це фінальний прогін системних тестів силами замовника», а насправді мета інша: не пошук дефектів, а рішення про готовність. Якщо UAT перетворюється на баг-хантинг — системний рівень не спрацював.
- Виглядає як «alpha — сирий білд, beta — майже готовий», а насправді ключова різниця в місці й контролі: альфа — на боці розробника під наглядом, бета — у реальних користувачів у їхньому середовищі.
- Виглядає як «unit-тести — внутрішня справа розробників, мануальному QA байдуже», а насправді покриття нижніх рівнів прямо визначає, що варто перевіряти руками, а що — марнування часу.
Підсумок
- Рівень визначається об'єктом тестування: модуль → зв'язки модулів → система цілком → система в руках користувача. Не інструментом і не технікою.
- Кожен рівень ловить свій клас дефектів: логіка — на модульному, стики й контракти — на інтеграційному, наскрізні сценарії й вимоги — на системному, відповідність бізнес-потребі — на приймальному.
- Чим нижче знайдено дефект, тим дешевше виправлення і точніша локалізація; big bang економить на підготовці, але платить пошуком дефекту по всій системі.
- Мета приймального рівня — не знайти дефекти, а ухвалити рішення про готовність; виконують його користувачі й бізнес, а не команда тестування.
- У V-моделі кожен рівень дзеркалить етап розробки: тест-базис визначає рівень, і тести рівня можна проєктувати, щойно готовий відповідний документ.
Що питають на співбесіді
- «Назвіть рівні тестування і поясніть різницю між ними.» Інтерв'юер чекає не перелік назв, а різницю в об'єкті й меті. Сильна відповідь для кожного рівня називає, що перевіряємо і який клас дефектів там ловиться.
- «Чим інтеграційне тестування відрізняється від системного?» Класична перевірка на розуміння: інтеграційне дивиться на стики між частинами, системне — на систему цілком проти вимог. Якщо відповідь зводиться до «інтеграційне — це менше, системне — більше», це провал.
- «Що таке big bang, top-down, bottom-up? Що таке stub і driver?» Тут дивляться, чи розумієш ціну кожного підходу: big bang — дорога локалізація, top-down — потрібні заглушки, bottom-up — драйвери.
- «Чим UAT відрізняється від системного тестування?» Очікують різницю в меті (рішення про готовність vs пошук дефектів), виконавцях і тест-базисі.
- «Alpha vs beta?» Перевірка на точність: місце і контроль, а не «ступінь сирості».
- «Регресійне тестування — це який рівень?» Питання-пастка на межу «рівні vs види»: регресія — вид, застосовний на будь-якому рівні.
- «Навіщо мануальному QA знати про unit-тести?» Дивляться на зрілість: розумієш ти покриття нижніх рівнів як вхідні дані для свого ручного фокусу — чи вважаєш усе, що не UI, чужою територією.
Джерела
- ISTQB CTFL Syllabus 4.0 — глава покриває розділ 2.2.1 «Test Levels» (п'ять рівнів, форми приймального тестування).
- ISTQB Glossary — канонічні означення: test level, component testing, stub, driver, alpha/beta testing.
- Martin Fowler — UnitTest — що таке unit-тест, межі ізоляції та чому означення «модуля» різниться між командами.
- Ham Vocke — The Practical Test Pyramid (martinfowler.com) — як рівні співвідносяться з вартістю і швидкістю тестів у сучасному стеку.
Назвіть рівні тестування і поясніть, чим вони відрізняються.
Класична модель — чотири рівні: модульний (unit), інтеграційний (integration), системний (system) і приймальний (acceptance). Розрізняє їх об'єкт тестування: окремий модуль в ізоляції → зв'язки між модулями → система цілком проти вимог → система в руках користувача. Кожен рівень має власну мету, власний тест-базис і власний типовий клас дефектів: логіка ловиться на модульному, стики й контракти — на інтеграційному, наскрізні сценарії — на системному, відповідність бізнес-потребі — на приймальному. Слабка відповідь — перелік назв; сильна для кожного рівня каже, що перевіряємо і які дефекти там живуть. Варто додати, що силабус ISTQB CTFL 4.0 виділяє п'ять рівнів — інтеграційний там розділено на компонентний і системний інтеграційний.
Чим рівень тестування відрізняється від виду тестування?
Рівень визначається об'єктом тестування (модуль, зв'язка модулів, система, система в руках користувача), а вид — метою чи характером перевірки: функціональне, регресійне, смоук. Ключова властивість видів — вони застосовні на будь-якому рівні: буває регресія на unit-рівні й регресія на системному, смоук білда і смоук окремого сервісу. Тому «смоук» чи «регресія» у відповіді на питання про рівні — типовий спосіб його завалити. Практичний наслідок: коли в тест-плані описуєш «регресійне тестування», окремо вказуєш, на яких рівнях воно проходить, — це різні активності з різними виконавцями.
Що таке модульне (unit) тестування і хто його виконує?
Модульне тестування перевіряє найменшу окрему частину коду — функцію, метод, клас — в ізоляції від решти системи. Пишуть і запускають такі тести зазвичай розробники, тим самим інструментарієм, що й сам код. Ізоляція означає, що зовнішні залежності підмінюються заглушками: якщо функція розрахунку знижки викликає базу даних, у тесті базу замінять імітацією — перевіряється логіка функції, а не робота бази. Звідси головна сила рівня: тест виконується за мілісекунди, не потребує середовища і точно вказує місце поломки — впав тест функції, отже дефект у цій функції.
Навіщо мануальному QA, який не пише unit-тести, розуміти цей рівень?
Це питання на зрілість, і суть відповіді — покриття нижніх рівнів визначає ручний фокус. По-перше, щоб не дублювати роботу: якщо межі й крайові значення функції покриті юнітами, ганяти руками двадцять комбінацій — марнування часу, ручні перевірки зміщуються туди, куди юніти не дістають (інтеграція, UI, реальні дані). По-друге, щоб грамотно тріажити баги: «знижка рахується неправильно» і «рахується правильно, але не відображається» — дефекти різних рівнів з різними адресатами. По-третє, щоб читати сигнали якості: зелені юніти в pull request — мінімальна гігієна білда, червоні — привід не починати ручний прогін узагалі. І нарешті, це перша сходинка до автоматизації: піраміда тестування будується саме на розумінні, що дешевше ловити внизу.
Що перевіряє інтеграційне тестування і які дефекти там типові?
Інтеграційне тестування перевіряє взаємодію між частинами: контракти, формати даних, послідовності викликів, обробку помилок на стиках. Типовий дефект цього рівня не видно всередині жодного окремого модуля — він живе саме між ними: модуль А повертає суму в копійках, модуль Б очікує в гривнях; сервіс А шле дату як 2026-07-16, сервіс Б парсить американський формат. Кожен модуль окремо при цьому проходить свої unit-тести — і саме тому «в нас усі юніти зелені» нічого не гарантує для зв'язки. Практичний наслідок: значна частина інтеграційних перевірок у сучасних проєктах іде через API, тому тестувальнику потрібні HTTP і REST як робочі інструменти.
Чим інтеграційне тестування відрізняється від системного?
Різниця в об'єкті: інтеграційне дивиться на стики між частинами, системне — на систему цілком проти вимог. Інтеграційний рівень перевіряє контракти, формати даних і обробку помилок між модулями чи сервісами; системний — наскрізні сценарії очима користувача на зібраній, розгорнутій системі з реальними інтеграціями, на середовищі, наближеному до продакшену. Різний і тест-базис: архітектура та контракти API проти вимог до системи. Відповідь у стилі «інтеграційне — це менше, системне — більше» — провал: різниця не в масштабі, а в тому, що саме є об'єктом перевірки. Лакмус: якщо на інтеграційному рівні ти тестуєш логіку всередині модуля — ти дублюєш unit-рівень і пропускаєш стики.
Що таке big bang, top-down і bottom-up? У чому ціна кожного підходу?
Це три класичні стратегії, у якому порядку збирати й перевіряти зв'язки між модулями. Big bang — зібрати все за один раз і тестувати готову зв'язку: підготовки нуль, але коли щось падає, дефект доводиться шукати по всій системі одразу — виправдано хіба для малих систем. Top-down іде від верхніх модулів до нижніх: скелет системи і головні сценарії видно рано, але відсутні нижні модулі треба підміняти заглушками (stubs), а низькорівнева логіка перевіряється останньою. Bottom-up — навпаки, від нижніх до верхніх: критична низькорівнева логіка перевіряється першою, але потрібні драйвери (drivers), а працюючу систему цілком видно лише наприкінці. Інтерв'юер тут дивиться, чи розумієш ти саме ціну: big bang — дорога локалізація, top-down — заглушки, bottom-up — драйвери.
Що таке stub і driver? Чим вони відрізняються?
Обидва — допоміжний код, який заміняє ще не готову чи не перевірену частину системи, а відрізняє їх напрямок підміни. Заглушка (stub) імітує нижній модуль, який викликають: спрощена імітація, що повертає заготовлені відповіді, — потрібна в top-down, коли верхні рівні вже інтегруються, а нижніх ще немає. Драйвер (driver) імітує верхній рівень: смикає модуль так, як смикав би відсутній код зверху, — потрібен у bottom-up, коли нижні модулі вже зібрані, а викликати їх ще нікому. Просте мнемонічне правило: stub відповідає на виклики, driver їх ініціює.
Чому на практиці інтеграцію проводять інкрементно, а не big bang?
Через вартість локалізації дефекту. Якщо з'єднати десятки модулів одразу і щось упаде (а щось упаде), шукати причину доведеться по всій системі; якщо інтегрувати по одному з'єднанню і перевіряти одразу — дефект локалізується миттєво, бо змінилось лише одне. Тому реальні команди комбінують підходи й рухаються інкрементно, а big bang лишається виправданим тільки для малих систем із кількох модулів. Це той самий принцип, що робить unit-рівень цінним: чим менший приріст між перевірками, тим точніше видно, де зламалось.
ISTQB CTFL 4.0 виділяє п'ять рівнів. Що за п'ятий і навіщо цей поділ?
П'ятий рівень з'являється з поділу інтеграційного на два: компонентний інтеграційний (component integration) — взаємодія модулів усередині системи, і системний інтеграційний (system integration) — взаємодія вашої системи з іншими системами: платіжним провайдером, поштовим сервісом. Поділ практичний, бо це різні задачі: всередині системи команда контролює обидві сторони стику, а зовнішню систему не контролює ніхто — інші релізні цикли, чужа документація, ліміти тестових середовищ. Питання «а як тестувати інтеграцію зі Stripe?» — це саме system integration. На співбесіді достатньо чотирьох рівнів, але згадка про цей поділ показує знання актуального силабуса.
Хто виконує системне тестування і чому важлива незалежність від розробників?
Системне тестування зазвичай виконує незалежна команда тестування — незалежна саме від авторів коду. Причина не бюрократична: свіже око без знання «як воно влаштоване всередині» знаходить те, повз що розробник пройде, бо він знає, як «треба» користуватись своїм кодом, і несвідомо тестує саме так. Об'єкт рівня — поведінка продукту очима користувача: наскрізні сценарії, функціональні й нефункціональні вимоги, робота на середовищі, наближеному до продакшену. Окремий клас знахідок цього рівня — розбіжності між вимогами і реалізацією: на нижніх рівнях їх не видно, бо там тест-базисом був дизайн коду, а не вимоги до продукту.
Чим UAT відрізняється від системного тестування?
Різниця в меті, виконавцях і тест-базисі. Системне тестування шукає дефекти: команда тестування перевіряє систему проти вимог до неї. UAT (user acceptance testing) відповідає на інше питання — чи готова система до впровадження і чи розв'язує вона задачу бізнесу: реальні користувачі або представники замовника перевіряють, чи можуть виконати свої бізнес-процеси, а тест-базис — бізнес-вимоги та acceptance criteria. Типовий результат UAT — не баг-репорт, а рішення: приймаємо / приймаємо з умовами / не приймаємо. Звідси практичний маркер: якщо UAT перетворився на баг-хантинг — це не «добре попрацювали», це системний рівень не спрацював, бо дефекти мали бути знайдені раніше.
У чому різниця між alpha- і beta-тестуванням?
Ключова різниця — місце і контроль, а не «ступінь готовності білда», як часто відповідають. Альфа: потенційні користувачі тестують продукт на боці розробника — на його середовищі, під наглядом команди. Бета: зовнішні користувачі тестують у себе — на власних пристроях, у власному оточенні, без нагляду. Саме тому бета незамінна для масових продуктів: вона ловить дефекти конфігурацій і сценаріїв, які неможливо відтворити в лабораторії, — екзотичні пристрої, мережі, локалі, звички користувачів. Відповідь «альфа — сирий білд, бета — майже готовий» — типова помилка, яку інтерв'юер і провокує цим питанням.
Які форми приймального тестування існують, крім UAT?
Операційне приймальне (operational acceptance) — готовність до експлуатації руками адміністраторів: бекапи й відновлення, моніторинг, встановлення та оновлення. Контрактне і регуляторне — відповідність контракту із замовником або вимогам регулятора; актуально для фінтеху, медицини, держсектору, де «працює» не дорівнює «можна впроваджувати». І дві форми з залученням користувачів: альфа-тестування на боці розробника під наглядом і бета-тестування в реальних користувачів у їхньому середовищі. Об'єднує всі форми мета рівня: не знайти дефекти, а ухвалити рішення про готовність — кожна форма перевіряє готовність зі свого боку: бізнес-процеси, експлуатація, юридичні зобов'язання, реальний світ.
Як рівні тестування пов'язані з V-моделлю і що означає «тест-базис визначає рівень»?
У V-моделі ліва гілка — деталізація від бізнес-вимог до коду, права — рівні тестування, і кожен рівень дзеркалить відповідний етап лівої гілки: модульний виводиться з детального дизайну, інтеграційний — з архітектури, системний — із системних вимог, приймальний — з вимог користувача. «Тест-базис визначає рівень» означає, що документ, з якого виведена перевірка, диктує, де її ганяти: перевірку з бізнес-вимоги безглуздо проганяти на unit-рівні — і навпаки. Другий практичний висновок: тести кожного рівня можна проєктувати, щойно пишеться відповідний документ, задовго до появи коду — це і є раннє тестування із семи принципів. Рев'ю вимог на лівій гілці дешевше за баг-репорт на правій.
Баг відтворюється лише на зв'язці двох сервісів, окремо кожен працює. Що це каже про рівень і як діяти?
Це класичний портрет дефекту інтеграційного рівня: проблема живе на стику — контракт, формат даних, послідовність викликів чи обробка помилки між сервісами, — тому всередині кожного окремого сервісу її й не видно, і unit-тести обох чесно зелені. Якщо другий сервіс зовнішній (платіжка, пошта) — це system integration. Практичні кроки: локалізувати сам стик — зняти реальні запит і відповідь між сервісами й порівняти з контрактом; у баг-репорті адресувати дефект тому, хто порушив контракт, а не «обом командам разом», і додати пару request/response як доказ. Для команди це ще й сигнал про діру в покритті: інтеграційна перевірка цього з'єднання пропущена, і без неї баг повернеться після наступного рефакторингу будь-якої зі сторін.
Три кейси, де рівні тестування перестають бути теорією: тріаж чотирьох багів однієї фічі за рівнями, планування ручного чеклиста поверх відомого unit-покриття і API-тест контракту на стику двох сервісів. Скрізь — та сама система координат: об'єкт тестування визначає рівень, рівень визначає адресата.
Кейс 1. Одна фіча — чотири баги на чотирьох рівнях
Фіча: знижка 10% для замовлень від 1000 грн. За тиждень тестування і UAT прилетіли чотири скарги, які виглядають як «знижка не працює». Насправді це чотири дефекти різних рівнів — і чотири різні адресати.
| Спостереження | Рівень дефекту | Кому і як адресувати |
|---|---|---|
| Знижка застосовується і до замовлення на 999 грн | Модульний: логіка порогу всередині функції розрахунку | Розробнику функції; вказати вхід і очікуваний результат — юніт на межу відсутній або неправильний |
| API повертає суму в копійках, кошик показує 90 000 грн замість 900 | Інтеграційний: контракт на стику API і фронтенду | Командам стику з парою request/response; винен той, хто порушив контракт |
| Знижка рахується правильно, але на кроці оплати кошик обнуляється | Системний: наскрізний сценарій ламається на переході між кроками | Баг-репорт з повним сценарієм від кошика до оплати; окремі кроки поодинці працюють |
| Все працює, але бухгалтерія не може вивантажити звіт за знижками | Приймальний: бізнес-процес не покритий вимогами | До аналітика або product owner; це розрив у вимогах, а не дефект коду |
Що дивитися і чому:
- Симптом один — «знижка не працює», а дефекти різні. Рівень визначає не формулювання скарги, а об'єкт: логіка функції, стик, наскрізний сценарій чи бізнес-потреба. Перше питання тріажу — «де саме живе розбіжність?».
- Другий рядок — найчастіша плутанина. «Рахується неправильно» і «рахується правильно, але відображається неправильно» — дефекти різних рівнів: перший шукають у функції, другий — на стику. Пара запит/відповідь з мережевої панелі відрізняє їх за хвилину: якщо в JSON сума правильна — фронт, якщо ні — бекенд.
- Четвертий рядок — не баг у звичному сенсі. Код відповідає вимогам, але задачу бізнесу не розв'язує. Саме такі знахідки — легітимний результат приймального рівня, і заводити їх треба як питання до вимог, а не як дефект розробнику.
- Багато знахідок нижніх рівнів на UAT — окремий сигнал. Якби всі чотири проблеми знайшла бухгалтерія на прийманні, це означало б, що модульний, інтеграційний і системний рівні не спрацювали: на UAT легітимна лише четверта.
Кейс 2. «Це покрито юнітами» — що лишається в ручному чеклисті
Розробник у pull request тієї самої фічі пише: «розрахунок знижки покритий юнітами — межі 999/1000, від'ємні суми, округлення». Це не «тестувати нічого», це вхідні дані для планування: юніти перевірили логіку функції в ізоляції — усе, що живе поза ізоляцією, лишається тобі.
| Перевірка | Уже ловлять юніти? | У ручний прогін? |
|---|---|---|
| Двадцять комбінацій сум навколо порогу 1000 грн | Так — межі й крайові значення покриті | Ні: дублювання, марнування часу |
| Знижка видна в кошику, в листі-підтвердженні та в PDF-інвойсі | Ні — юніти не бачать UI й інтеграцій | Так: це стики і система цілком |
| Знижка на реальних даних: товар з акції, замовлення з двох валют | Ні — юніти працюють на синтетичних значеннях | Так: реальні дані — класика системного рівня |
| Поведінка кошика, коли сервіс знижок не відповідає | Ні — обробка помилок на стику | Так: інтеграційний сценарій, який юніт не відтворить |
Що дивитися і чому:
- Перед прогоном подивись на сам PR. Зелені юніти — мінімальна гігієна білда; червоні — привід не починати ручний прогін узагалі, бо тестуватимеш свідомо зламану збірку.
- «Покрито юнітами» звужує, а не скасовує ручну роботу. Фокус зміщується туди, куди юніти не дістають: інтеграція, UI, реальні дані, наскрізні сценарії. Це і є практичне застосування рівнів: не перевіряти на своєму рівні те, що вже спіймано нижче.
- Довіряй, але дивись, що саме покрито. «Покрито юнітами» без переліку кейсів — не аргумент: спитати «а межа 999/1000 там є?» дешевше, ніж пропустити дефект на порозі знижки.
Кейс 3. Контракт на стику: інтеграційна перевірка через API
Сервіс замовлень віддає дату доставки сервісу нотифікацій. Обидва сервіси зелені на своїх юнітах, але листи приходять з датою «11 липня» замість «7 листопада»: контракт стику вимагає ISO 8601 (2026-11-07), замовлення шлють 07/11/2026 (день/місяць), а нотифікації парсять це як американський MM/DD/YYYY. Дефект живе рівно на стику — і перевіряється без UI, дешевим API-тестом:
import { test, expect } from '@playwright/test';
test('контракт: дата доставки — ISO 8601, сума — в копійках', async ({ request }) => {
const res = await request.get('/api/orders/12345');
expect(res.status()).toBe(200);
const order = await res.json();
// контракт стику: YYYY-MM-DD, а не DD/MM чи MM/DD
expect(order.deliveryDate).toMatch(/^\d{4}-\d{2}-\d{2}$/);
// контракт стику: ціле число копійок, не рядок і не дробові гривні
expect(Number.isInteger(order.totalAmount)).toBe(true);
});
Що дивитися і чому:
- Об'єкт тесту — контракт, а не логіка. Тест не перевіряє, чи правильно порахована знижка (це юніти) і чи гарний лист (це системний рівень) — лише формат даних на стику. Падіння такого тесту одразу каже «зламано контракт», без пошуку по всій системі.
- Це і є альтернатива big bang у мініатюрі. Перевірити одне з'єднання окремо дешевше, ніж збирати все й дивитись на дивну дату в листі: локалізація миттєва, бо перевіряється рівно один стик.
- Якщо друга сторона стику зовнішня (платіжний провайдер, поштовий сервіс) — це вже системна інтеграція (system integration) за ISTQB 4.0: контракт той самий, але чужу сторону не полагодиш, тож тест ще й документує, на яку саме поведінку зовнішньої системи ви розраховуєте.
- Такий тест — регресійна страховка стику. Рефакторинг будь-якого з сервісів, який тихо змінить формат, впаде тут, а не в продакшен-листах: саме так інтеграційний рівень ловить свій клас дефектів раніше за системний.
Карта рівнів
- Знаю чотири класичні рівні (модульний, інтеграційний, системний, приймальний) і що розрізняє їх об'єкт тестування, а не інструмент чи техніка.
- Можу пояснити межу «рівень vs вид»: смоук, регресія, функціональне — види, застосовні на будь-якому рівні; «регресія — це рівень» — типовий провал на співбесіді.
- Можу для кожного рівня назвати типовий клас дефектів: логіка модуля → стики й контракти → наскрізні сценарії й вимоги → відповідність бізнес-потребі.
- Знаю, що ISTQB CTFL 4.0 виділяє п'ять рівнів: інтеграційний розділено на компонентний інтеграційний (усередині системи) і системний інтеграційний (з зовнішніми системами — Stripe, поштовий сервіс).
Модульний рівень
- Розумію, що unit-тест перевіряє найменшу частину коду в ізоляції, а залежності (база, мережа) підмінюються заглушками.
- Знаю головну силу рівня: мілісекунди на прогін, без середовища, точна локалізація — впав тест функції, дефект у функції.
- Можу пояснити, навіщо unit-покриття мануальному QA: не дублювати перевірки руками, тріажити баги за рівнями, читати сигнали якості білда (червоні юніти — не починати прогін).
Інтеграційний рівень
- Розумію, що інтеграційний рівень перевіряє взаємодію — контракти, формати даних, послідовності викликів, обробку помилок на стиках, — а не модулі повторно.
- Можу навести приклад дефекту, якого не видно всередині жодного модуля: копійки vs гривні, ISO-дата vs американський формат.
- Знаю три підходи до збирання і ціну кожного: big bang — пошук дефекту по всій системі, top-down — потрібні заглушки, bottom-up — потрібні драйвери; на практиці інтегрують інкрементно — одне з'єднання за раз дає миттєву локалізацію.
- Можу пояснити різницю stub vs driver: заглушка імітує нижній модуль і відповідає на виклики, драйвер імітує верхній рівень і сам викликає.
Системний і приймальний рівні
- Знаю об'єкт системного рівня: система цілком — зібрана, розгорнута, з реальними інтеграціями — проти вимог, на середовищі, наближеному до продакшену.
- Можу пояснити, чому системне тестування виконує незалежна команда: свіже око проти «розробник знає, як треба користуватись своїм кодом».
- Розумію мету приймального рівня: рішення про готовність (приймаємо / з умовами / не приймаємо), а не пошук дефектів; багато багів на UAT — сигнал, що системний рівень не спрацював.
- Знаю форми приймального: UAT, операційне (бекапи, моніторинг, оновлення), контрактне/регуляторне, alpha, beta.
- Можу пояснити різницю alpha vs beta через місце і контроль: у розробника під наглядом vs у користувачів у їхньому середовищі — а не через «ступінь сирості білда».
V-модель і відповідальність
- Розумію, як рівні дзеркалять етапи лівої гілки V-моделі, і можу сформулювати правило «тест-базис визначає рівень».
- Знаю тест-базис кожного рівня: детальний дизайн і код → архітектура й контракти API → вимоги до системи → бізнес-вимоги та acceptance criteria.
- Можу пояснити, чому тести рівня проєктують, щойно готовий відповідний документ: це раннє тестування, рев'ю вимог дешевше за баг-репорт.
- Знаю типовий розподіл виконавців (розробники → розробники і тестувальники → незалежна команда → користувачі й бізнес) і що в Agile межі розмиваються, але логіка «нижче — ближче до коду, вище — до бізнесу» зберігається.
Що визначає рівень тестування?
Питання
Що таке рівень тестування?