Статичне тестування і рев'ю
Зміст
Найдорожчі баги народжуються не в коді. Вони народжуються у реченні вимоги, яке кожен у команді зрозумів по-своєму, і спокійно живуть там тижнями — поки розробник пише код під своє розуміння, а QA готує тест-кейси під власне. Коли розбіжність нарешті спливає на тестуванні, переписувати доводиться все: вимогу, код, тести. А можна було знайти її за пʼять хвилин уважного читання — ще до того, як хтось відкрив редактор.
Саме про це статичне тестування (static testing): перевірка робочих продуктів без виконання коду — читанням, обговоренням, аналізом. На співбесідах для джуна ця тема звучить нечасто і зазвичай у форматі «чим статичне відрізняється від динамічного». Але в щоденній роботі це одна з найцінніших навичок: QA, який ставить правильні питання до вимог на рефайнменті, приносить команді більше користі, ніж той, хто мовчки чекає на білд.
Статичне vs динамічне тестування
Динамічне тестування (dynamic testing) — це все, що ти звик називати «тестуванням»: запускаємо застосунок, подаємо входи, порівнюємо фактичну поведінку з очікуваною. Для цього потрібні працюючий білд, тестове середовище і дані (докладніше — у главі про тестові середовища).
Статичне тестування коду не виконує. Обʼєкт перевірки — сам артефакт як текст: вимога, схема, код, тест-кейс. Тому воно доступне з першого дня проєкту, коли динамічному тестуванню ще просто нічого запускати.
Є і глибша відмінність — у тому, що саме знаходиться. Динамічний тест бачить відмову (failure) — зовнішній прояв проблеми: неправильну цифру на екрані, помилку 500. Щоб дістатися від відмови до самого дефекту в коді, потрібен ще дебаг. Статичне тестування знаходить дефект (defect) безпосередньо: ти дивишся прямо в суперечливе речення вимоги чи проблемний рядок коду, і шукати більше нічого не треба. Ланцюжок error → defect → failure ми розбирали у базових поняттях.
| Критерій | Статичне | Динамічне |
|---|---|---|
| Виконання коду | Ні | Так |
| Що потрібно | Артефакт, який можна прочитати | Білд, середовище, дані |
| Що знаходить | Дефект напряму | Відмову, дефект — після дебагу |
| Коли доступне | З перших днів проєкту | Коли є що запустити |
| Хто/що виконує | Люди (рев'ю) та інструменти (статичний аналіз) | Люди й автотести на працюючій системі |
Підходи не конкурують — вони ловлять різні класи дефектів. Тільки статикою знаходяться: суперечність між двома вимогами, недосяжний код, невикористана змінна, відхилення від стандарту кодування, пропущена вимога. Тільки динамікою: реальна швидкодія під навантаженням, поведінка на живих інтеграціях, проблеми з памʼяттю. Тому «ми зробили ретельне рев'ю, тестувати не треба» — так само хибно, як і «навіщо читати вимоги, все одно все перевіримо руками».
Що перевіряють без запуску коду
Майже будь-який робочий продукт (work product), який можна прочитати:
- Вимоги, user story, acceptance criteria — найвигідніший обʼєкт: дефект тут ще нічого не коштує виправити (структуру й атрибути хороших вимог розбираємо у главі про вимоги);
- архітектура і дизайн — схеми, описи інтеграцій, контракти API;
- код — класичне код-рев'ю в pull request;
- тестові артефакти — тест-плани, тест-кейси і чеклисти: свіже око колеги ловить пропущені негативні сценарії та кроки, очевидні лише автору;
- документація і конфігурація — інструкції з розгортання, CI-конфіги, юзер-гайди.
Окремо підкресли для себе передостанній пункт: рев'ю тест-кейсів — це теж статичне тестування, і воно двічі корисне для джуна. Твої кейси стають кращими після чужих коментарів, а читання чужих — найшвидший спосіб перейняти досвід сеньйора.
Типи рев'ю: від коментаря в PR до інспекції
ISTQB виділяє чотири типи рев'ю за зростанням формальності. Розрізняються вони не «суворістю обличчя», а трьома речами: хто веде процес, чи обовʼязкова індивідуальна підготовка і наскільки задокументований результат.
Неформальне рев'ю (informal review) — без визначеного процесу і обовʼязкового протоколу. Попросив колегу глянути тест-кейси, кинув драфт вимоги в чат, отримав коментар у PR — це воно. Найдешевший і на практиці найпоширеніший тип: у більшості команд саме такі рев'ю переважають.
Walkthrough — веде сам автор: показує артефакт крок за кроком, пояснює логіку, збирає фідбек. Головні цілі — не стільки знайти дефекти, скільки досягти спільного розуміння і навчити: новачок після walkthrough архітектури розуміє систему краще, ніж після тижня самостійного читання. Підготовка рецензентів заздалегідь — необовʼязкова.
Технічне рев'ю (technical review) — рецензенти є технічними експертами у предметі, а веде зустріч фасилітатор (модератор), не автор. Індивідуальна підготовка перед обговоренням обовʼязкова. Ціль — досягти консенсусу і ухвалити технічне рішення: чи годиться такий дизайн інтеграції, чи безпечна така схема міграції.
Інспекція (inspection) — найформальніший тип. Повний визначений процес, чеклисти і правила, чітко розділені ролі (автор не може бути ані модератором, ані секретарем), обовʼязкова підготовка, формальний протокол і збір метрик. Головна ціль — знайти максимум дефектів; додаткова — покращити сам процес розробки, аналізуючи, звідки дефекти беруться.
| Неформальне | Walkthrough | Технічне рев'ю | Інспекція | |
|---|---|---|---|---|
| Хто веде | будь-хто | автор | фасилітатор | фасилітатор |
| Підготовка заздалегідь | ні | необовʼязкова | обовʼязкова | обовʼязкова |
| Документований результат | необовʼязковий | залежить від цілі | так | так, формальний |
| Головна ціль | швидкий фідбек | спільне розуміння, навчання | консенсус, технічне рішення | максимум дефектів, метрики |
У формальних рев'ю є стандартний набір ролей: автор (створив артефакт і виправляє знахідки), модератор/фасилітатор (веде процес і стежить, щоб обговорення не скотилося у суперечку), секретар (scribe) — фіксує знахідки, рецензенти — власне шукають дефекти, менеджер — виділяє час і людей. В неформальному рев'ю все це згортається до «автор + той, кого попросили глянути».
Сам процес рев'ю (за ISO/IEC 20246, на якому базується ISTQB) складається з пʼяти активностей: планування → ініціація → індивідуальне рев'ю → обговорення знахідок → виправлення і звітування. Індивідуальне рев'ю виділене недарма: найбільше дефектів знаходять саме тоді, коли кожен рецензент читає артефакт наодинці, у своєму темпі. Звичка «прочитаю по діагоналі прямо на зустрічі» вбиває головну цінність процесу.
Звичне код-рев'ю у pull request на цій шкалі — неформальне рев'ю, іноді з елементами технічного (обовʼязковий апрув, чеклист у шаблоні PR). Знати про це корисно на співбесіді: питання «які типи рев'ю бували у вас на проєкті» не має заганяти тебе в ступор через те, що інспекцій за Фаганом ти не бачив. Мало хто бачив — у сучасних Agile-командах переважають неформальні рев'ю і walkthrough, а формальна інспекція здебільшого лишилася в регульованих доменах (авіоніка, медицина).
Статичний аналіз: коли артефакт читає машина
Статичний аналіз (static analysis) — це те саме статичне тестування, тільки виконують його інструменти. Вони розбирають код (або конфіг, або схему) як структуру — без виконання — і шукають відомі класи проблем:
- лінтери (ESLint) — підозрілі патерни й порушення домовленостей: невикористані змінні, недосяжний код, небезпечні конструкції;
- перевірка типів (компілятор TypeScript,
tsc) — виклик неіснуючого методу, неправильний тип аргументу, звертання до поля, якого може не бути; - сканери безпеки й залежностей — відомі вразливості у сторонніх пакетах, секрети, закомічені в репозиторій;
- аналізатори складності (SonarQube тощо) — метрики на кшталт цикломатичної складності, задубльований код.
Для AQA це не абстракція: статичний аналіз щодня рятує тестовий код. Класичний приклад — забутий await у Playwright:
test('користувач бачить дашборд після логіну', async ({ page }) => {
page.goto('/login'); // забутий await: тест побіжить далі, не дочекавшись переходу
await page.getByLabel('Email').fill('user@example.com');
});
Динамічно цей дефект проявиться як флакі-тест — падатиме через раз, і причину шукатимуть годинами. Статично його ловить правило @typescript-eslint/no-floating-promises прямо в редакторі, підкресливши рядок ще до першого запуску. Це найкоротша ілюстрація цінності статики: та сама проблема, знайдена за секунду замість години.
Лінтер і перевірка типів зазвичай вбудовані у пайплайн: код, який їх не проходить, просто не потрапляє в основну гілку (як це влаштовано — у розділі про Git і CI/CD).
Чому статика — найдешевша
Вартість виправлення дефекту зростає з кожним етапом, на якому він доживає (ми торкалися цього у базових поняттях). Дефект у вимозі, знайдений на рев'ю вимоги, — це виправлене речення. Той самий дефект, знайдений на тестуванні, — це переписаний код, перероблені тест-кейси і новий цикл регресії. А в продакшені — це ще й хотфікс, зіпсовані дані користувачів і незручна розмова з бізнесом. Саме на цьому стоїть принцип раннього тестування з семи принципів: чим раніше знайдено — тим дешевше виправити.
Статичне тестування — найраніше з можливих, і в цьому його економіка:
- Не потрібна інфраструктура. Ні білда, ні середовища, ні тестових даних — лише артефакт і уважний читач.
- Дефект знаходиться напряму. Без дебагу, без відтворення, без «а на моєму стенді не відтворюється».
- Ловиться те, що динаміка не побачить ніколи. Динамічний тест перевіряє код проти вимоги; якщо дефект у самій вимозі — тест чесно пройде, перевіривши неправильну поведінку.
Чесне застереження: «найдешевша» не означає «безкоштовна» і не означає «достатня». Рев'ю коштує часу кваліфікованих людей, а вимкнена статика нічого не скаже про те, чи система взагалі працює. Це перша лінія оборони, а не заміна всім наступним.
Роль QA у рев'ю вимог
QA — перша людина, яка «виконує» вимогу, нехай поки що подумки. Розробник читає вимогу з питанням «як це зробити», QA — з питанням «як це зламати і як я це перевірю». Тому на рефайнменті чи рев'ю специфікації QA шукає конкретні класи дефектів:
- Неоднозначність. «Пошук має працювати швидко» — це скільки? 200 мс чи 2 секунди? На якому обсязі даних? Поки немає числа, вимогу неможливо ані реалізувати однозначно, ані перевірити.
- Неповнота. «Користувач може завантажити файл» — які формати? Який максимальний розмір? Що побачить користувач при перевищенні? Кожне питання без відповіді — майбутній баг-репорт зі статусом «а це взагалі баг чи так задумано?».
- Суперечності. У сторі написано «неактивні акаунти видаляються через 90 днів», а в сусідній — «історія замовлень зберігається завжди». Обидві не можуть бути правдою одночасно.
- Тестопридатність (testability). Головний фільтр QA: якщо до вимоги неможливо придумати перевірку з очікуваним результатом — вимога не готова. Це практичний сенс критеріїв Definition of Ready у Scrum-процесі.
Кожне таке питання, поставлене до початку розробки, — це дефект, який не був написаний: його не треба ловити тестами, репортити, чинити й перевіряти. Формат хороших acceptance criteria, які роблять вимогу перевірною за побудовою, розбираємо у главі про вимоги та user story.
І правило гігієни, спільне для будь-якого рев'ю: коментарі стосуються артефакту, а не людини. «У кроці 3 не описано поведінку при таймауті» працює; «ти знову написав неповний кейс» — руйнує довіру, і наступного разу тобі просто не принесуть драфт на рев'ю.
Типові помилки
- Виглядає як «статичне тестування — це тестування статичних сторінок або коду, який не змінюється», а насправді «статичне» стосується способу перевірки: артефакт не виконується. Сам артефакт може змінюватися хоч щодня.
- Виглядає як «рев'ю — це синонім код-рев'ю», а насправді рев'ювлять будь-який робочий продукт: вимоги, архітектуру, тест-кейси, документацію. Для QA рев'ю вимог важливіше за рев'ю коду.
- Виглядає як «лінтер зелений — значить, код правильний», а насправді статичний аналіз бачить форму, а не поведінку: він зловить забутий
await, але не скаже, що тест перевіряє не той інваріант. - Виглядає як «walkthrough та інспекція — однакові зустрічі з різними назвами», а насправді walkthrough веде автор із ціллю досягти спільного розуміння, а інспекцію — фасилітатор за формальним процесом із ціллю знайти максимум дефектів.
- Виглядає як «QA підключається, коли зʼявляється білд», а насправді найдешевші знахідки QA робить до першого рядка коду — питаннями до вимог.
Підсумок
- Статичне тестування перевіряє артефакти без виконання коду і тому доступне з першого дня проєкту; воно знаходить дефект напряму, тоді як динамічне бачить відмову, від якої до дефекту ще треба дійти дебагом.
- Рев'ювлять будь-який читабельний робочий продукт — вимоги, код, тест-кейси, архітектуру; рев'ю тест-кейсів — теж статичне тестування.
- Чотири типи рев'ю за зростанням формальності: неформальне → walkthrough (веде автор, ціль — спільне розуміння) → технічне рев'ю (веде фасилітатор, ціль — консенсус) → інспекція (формальний процес, ціль — максимум дефектів).
- Статичний аналіз — це статичне тестування інструментами: лінтери, перевірка типів, сканери; для AQA це щоденний захист тестового коду від дефектів на кшталт забутого
await. - Статика — найдешевша точка знаходження дефекту, бо не потребує білда й середовища, а дефект у вимозі, знайдений на рев'ю, коштує одне виправлене речення. Але вона доповнює динамічне тестування, а не замінює його.
Що питають на співбесіді
- «Чим статичне тестування відрізняється від динамічного?» — базове питання-фільтр. Очікувана відповідь: без виконання коду vs із виконанням, плюс наслідки — статика доступна раніше і знаходить дефект напряму. Сильний кандидат додає приклад дефекту, який ловиться лише статикою (суперечність у вимогах).
- «Які типи рев'ю знаєш?» — чотири типи за формальністю. Інтервʼюер дивиться, чи розрізняєш walkthrough й інспекцію (хто веде і навіщо), а не просто перелічуєш назви.
- «Що таке статичний аналіз? Чим відрізняється від рев'ю?» — рев'ю виконують люди, аналіз — інструменти. Плюс балів — конкретика зі свого стека: ESLint, перевірка типів TypeScript.
- «Навіщо тестувальнику брати участь у рев'ю вимог?» — тут перевіряють зрілість: очікують аргумент про вартість дефекту і тестопридатність, а не «бо так написано в процесі».
- «Наведи приклад, коли рев'ю зекономило команді час» — питання на практичний досвід. Годиться навіть маленький кейс: питання на рефайнменті, яке виявило неузгодженість, або коментар у PR колеги, який зловив пропущений негативний сценарій. Інтервʼюер слухає, чи є за теорією реальна звичка.
Джерела
- ISTQB CTFL 4.0 Syllabus — ця глава покриває розділ 3 «Static Testing»; процес рев'ю у силабусі базується на стандарті ISO/IEC 20246.
- ISTQB Glossary — канонічні означення термінів: static testing, review, inspection, static analysis.
- Документація ESLint — як влаштований лінтинг JavaScript/TypeScript.
- Правило no-floating-promises у typescript-eslint — правило, яке статично ловить забутий
await; найкорисніше для тестового коду.
Що таке статичне тестування і чим воно відрізняється від динамічного?
Статичне тестування (static testing) — перевірка робочих продуктів без виконання коду: читанням, обговоренням, аналізом артефакту як тексту. Динамічне тестування (dynamic testing) — навпаки: запускаємо застосунок, подаємо входи, порівнюємо фактичну поведінку з очікуваною, а для цього потрібні білд, середовище і дані. Звідси два практичні наслідки. Статичне тестування доступне з першого дня проєкту, коли динамічному ще просто нічого запускати. І воно знаходить дефект (defect) напряму — ти дивишся прямо в суперечливе речення вимоги чи проблемний рядок коду, — тоді як динамічний тест бачить лише відмову (failure), від якої до дефекту ще треба дійти дебагом. Сильна відповідь завершується прикладом дефекту, який ловиться тільки статикою: суперечність між двома вимогами жоден запуск застосунку не покаже.
Що можна перевіряти статичним тестуванням, окрім коду?
Майже будь-який робочий продукт (work product), який можна прочитати: вимоги, user story й acceptance criteria, архітектурні схеми та контракти API, тест-плани й тест-кейси, документацію, CI-конфіги, інструкції з розгортання. Найвигідніший обʼєкт — вимоги: дефект у них ще нічого не коштує виправити, це одне змінене речення. Окремо варто згадати рев'ю тест-кейсів: це теж статичне тестування, і для QA воно двічі корисне — власні кейси стають кращими після чужих коментарів, а читання чужих — найшвидший спосіб перейняти досвід сильніших колег.
Статичне тестування знаходить дефект чи відмову? У чому різниця?
Дефект — напряму, і це його головна перевага. Відмова — зовнішній прояв проблеми: неправильна цифра на екрані, помилка 500; саме її бачить динамічний тест, і щоб дістатися від відмови до дефекту в коді, потрібен ще дебаг. Статичне тестування працює з артефактом безпосередньо: рецензент дивиться в проблемний рядок або суперечливе речення, і шукати більше нічого не треба. Практичний наслідок — жодних «на моєму стенді не відтворюється»: відтворювати нічого, дефект уже знайдено і показано пальцем.
Які дефекти можна знайти лише статичним тестуванням, а які — лише динамічним?
Тільки статикою знаходяться: суперечність між двома вимогами, пропущена вимога, недосяжний код, невикористана змінна, відхилення від стандарту кодування. Тільки динамікою: реальна швидкодія під навантаженням, поведінка на живих інтеграціях, проблеми з памʼяттю. Підходи не конкурують — вони ловлять різні класи дефектів, тому «ми зробили ретельне рев'ю, тестувати не треба» — так само хибно, як «навіщо читати вимоги, все одно все перевіримо руками». Це питання часто ставлять саме щоб перевірити, чи розумієш взаємодоповнення, а не завчив означення.
Які типи рев'ю виділяє ISTQB?
Чотири, за зростанням формальності: неформальне рев'ю (informal review), walkthrough, технічне рев'ю (technical review), інспекція (inspection). Розрізняються вони не «суворістю», а трьома речами: хто веде процес, чи обовʼязкова індивідуальна підготовка рецензентів і наскільки задокументований результат. Неформальне — без визначеного процесу і протоколу: коментар у PR, «глянь мої кейси». Walkthrough веде сам автор із ціллю досягти спільного розуміння. Технічне рев'ю веде фасилітатор, рецензенти — технічні експерти, ціль — консенсус щодо технічного рішення. Інспекція — повний формальний процес із ролями, чеклистами, протоколом і метриками, ціль — знайти максимум дефектів. Інтервʼюер дивиться, чи розрізняєш типи за суттю, а не просто перелічуєш назви.
Чим walkthrough відрізняється від інспекції?
Двома головними осями: хто веде і навіщо. Walkthrough веде сам автор — показує артефакт крок за кроком, пояснює логіку, збирає фідбек; головна ціль — не стільки знайти дефекти, скільки досягти спільного розуміння і навчити (новачок після walkthrough архітектури розуміє систему краще, ніж після тижня самостійного читання); підготовка рецензентів необовʼязкова. Інспекція — найформальніший тип: веде фасилітатор, автор не може бути ані модератором, ані секретарем, підготовка обовʼязкова, є формальний протокол і збір метрик; головна ціль — знайти максимум дефектів, додаткова — покращити сам процес розробки, аналізуючи, звідки дефекти беруться. Плутати їх на співбесіді — типова помилка, бо зовні обидва виглядають як «зустріч над документом».
Хто веде технічне рев'ю і яка його ціль?
Веде фасилітатор (модератор), а не автор — це принципова відмінність від walkthrough. Рецензенти — технічні експерти в предметі, індивідуальна підготовка перед обговоренням обовʼязкова. Ціль — досягти консенсусу й ухвалити технічне рішення: чи годиться такий дизайн інтеграції, чи безпечна така схема міграції. Тобто технічне рев'ю — це не «пошукаємо помилки в тексті», а формат ухвалення інженерних рішень із задокументованим результатом.
Які ролі є у формальному рев'ю?
Пʼять стандартних: автор (створив артефакт і виправляє знахідки), модератор/фасилітатор (веде процес і стежить, щоб обговорення не скотилося в суперечку), секретар (scribe) — фіксує знахідки, рецензенти — власне шукають дефекти, менеджер — виділяє час і людей. В інспекції ролі розділені жорстко: автор не може бути ані модератором, ані секретарем. У неформальному рев'ю все це згортається до «автор плюс той, кого попросили глянути» — і це нормально, формальність має відповідати ризику артефакту.
З яких активностей складається процес рев'ю і на якій знаходять найбільше дефектів?
За ISO/IEC 20246 (на якому базується ISTQB) активностей пʼять: планування → ініціація → індивідуальне рев'ю → обговорення знахідок → виправлення і звітування. Найбільше дефектів знаходять на індивідуальному рев'ю — коли кожен рецензент читає артефакт наодинці, у своєму темпі. Саме тому звичка «прочитаю по діагоналі прямо на зустрічі» вбиває головну цінність процесу: на обговорення приходять без знахідок, і зустріч перетворюється на колективне читання вголос. Сильний кандидат наголошує саме на цій активності, а не просто перелічує етапи.
Куди на шкалі формальності потрапляє звичайне код-рев'ю в pull request?
Це неформальне рев'ю, іноді з елементами технічного — коли є обовʼязковий апрув чи чеклист у шаблоні PR. У сучасних Agile-командах переважають саме неформальні рев'ю і walkthrough, а формальна інспекція здебільшого лишилася в регульованих доменах на кшталт авіоніки й медицини. Тому питання «які типи рев'ю бували у вас на проєкті» не має заганяти в ступор: чесна відповідь «неформальні рев'ю в PR і walkthrough на рефайнментах» — цілком нормальна, якщо можеш пояснити, де ці формати стоять на загальній шкалі.
Що таке статичний аналіз і чим він відрізняється від рев'ю?
Статичний аналіз (static analysis) — те саме статичне тестування, тільки виконують його інструменти, а не люди: вони розбирають код, конфіг чи схему як структуру — без виконання — і шукають відомі класи проблем. Рев'ю виконують люди, і воно ловить те, що формальним правилом не опишеш: суперечності, пропущені сценарії, неправильний інваріант. Класи інструментів: лінтери (ESLint) — підозрілі патерни й порушення домовленостей; перевірка типів (компілятор TypeScript, tsc); сканери безпеки й залежностей — відомі вразливості в пакетах, закомічені секрети; аналізатори складності (SonarQube) — цикломатична складність, задубльований код. Плюс балів на співбесіді — конкретика зі свого стека, а не абстрактне «є такі інструменти».
Наведи приклад дефекту в тестовому коді, який ловить статичний аналіз.
Класика для AQA — забутий await перед page.goto() у Playwright: тест побіжить далі, не дочекавшись переходу. Динамічно цей дефект проявиться як флакі-тест — падатиме через раз, і причину шукатимуть годинами, бо симптом залежить від таймінгів. Статично його ловить правило @typescript-eslint/no-floating-promises прямо в редакторі, підкресливши рядок ще до першого запуску. Це найкоротша ілюстрація цінності статики: та сама проблема, знайдена за секунду замість години. У зрілих командах лінтер і перевірка типів вбудовані в пайплайн: код, який їх не проходить, просто не потрапляє в основну гілку.
Чому кажуть, що статичне тестування — найдешевше?
Вартість виправлення дефекту зростає з кожним етапом, на якому він доживає, а статика — найраніша з можливих точок знаходження. Дефект у вимозі, знайдений на рев'ю, — це виправлене речення; той самий дефект на тестуванні — переписаний код, перероблені тест-кейси й новий цикл регресії; у продакшені — ще й хотфікс і зіпсовані дані. Конкретні причини дешевизни: не потрібна інфраструктура (ні білда, ні середовища, ні даних — лише артефакт і уважний читач), дефект знаходиться напряму без дебагу, і ловиться те, що динаміка не побачить ніколи. Чесне застереження, яке варто озвучити: «найдешевша» не означає «безкоштовна» (рев'ю коштує часу кваліфікованих людей) і не означає «достатня» — це перша лінія оборони, а не заміна всім наступним.
Навіщо тестувальнику брати участь у рев'ю вимог і що він там шукає?
QA — перша людина, яка «виконує» вимогу, нехай поки що подумки: розробник читає її з питанням «як це зробити», QA — «як це зламати і як я це перевірю». Конкретні класи дефектів: неоднозначність («пошук має працювати швидко» — це 200 мс чи 2 секунди, на якому обсязі даних?), неповнота («користувач може завантажити файл» — які формати, який максимальний розмір, що при перевищенні?), суперечності (одна сторі каже «неактивні акаунти видаляються через 90 днів», сусідня — «історія замовлень зберігається завжди»), тестопридатність (testability) — головний фільтр: якщо до вимоги неможливо придумати перевірку з очікуваним результатом, вимога не готова. Кожне таке питання, поставлене до початку розробки, — дефект, який не був написаний: його не треба ловити тестами, репортити, чинити й перевіряти. На співбесіді тут очікують аргумент про вартість дефекту, а не «бо так написано в процесі».
Чи може дефект у вимозі пройти повз динамічне тестування? Чому?
Може — і майже завжди проходить, у цьому головна пастка. Динамічний тест перевіряє код проти вимоги: очікуваний результат тесту береться саме з неї. Якщо дефект у самій вимозі, розробник реалізує хибну поведінку, тест-кейс опише ту саму хибну поведінку як очікувану — і тест чесно пройде, перевіривши неправильну систему. Зловити такий дефект може лише статика: уважне читання, яке помітить суперечність із сусідньою вимогою чи питання без відповіді. Це найсильніший аргумент, чому рев'ю вимог для QA важливіше за рев'ю коду.
Чому «лінтер зелений» не означає «код правильний»?
Статичний аналіз бачить форму, а не поведінку. Він зловить забутий await, невикористану змінну, виклик неіснуючого методу — усе, що виражається структурним правилом. Але він не скаже, що тест перевіряє не той інваріант, що асерт стоїть не на тому елементі, що логіка кроку не відповідає вимозі: для цього треба розуміти намір, а намір читають люди на рев'ю. Тому статичний аналіз і рев'ю доповнюють одне одного всередині самої статики — так само, як статика в цілому доповнює динаміку, — і зелений пайплайн лінтера знімає лише один клас ризиків, а не питання якості загалом.
Як формулювати коментарі на рев'ю, щоб вони працювали?
Правило гігієни, спільне для будь-якого рев'ю: коментар стосується артефакту, а не людини. «У кроці 3 не описано поведінку при таймауті» — працює: це перевірюване твердження про текст, з яким можна щось зробити. «Ти знову написав неповний кейс» — руйнує довіру, переводить розмову в захист, і наступного разу драфт на рев'ю просто не принесуть. Це не про ввічливість заради ввічливості, а про економіку процесу: рев'ю живе доти, доки автори добровільно несуть свої артефакти під чуже око, і один токсичний рецензент здатен зупинити цей потік швидше, ніж будь-яка нестача часу.
Три кейси статичного тестування з робочого життя QA: рев'ю user story на рефайнменті (які питання поставити і який клас дефекту за кожним стоїть), рев'ю тест-кейсу колеги (що шукати і як формулювати коментарі) і статичний аналіз тестового коду — забутий await, який лінтер ловить до першого запуску.
Кейс 1. Рефайнмент: читаємо user story як QA
Команда бере в спринт сторі про експорт замовлень. Драфт виглядає цілком пристойно — саме такі й небезпечні:
Як менеджер, я хочу експортувати список замовлень у файл,
щоб аналізувати продажі без доступу до системи.
Acceptance criteria:
1. На сторінці замовлень є кнопка «Експорт».
2. Експорт працює швидко.
3. Файл містить усі замовлення.
Розробник читає це з питанням «як зробити» — і йому все зрозуміло: кнопка, запит, файл. QA читає з питанням «як я це перевірю» — і сторі розсипається:
| Фрагмент | Питання QA | Клас дефекту |
|---|---|---|
| «у файл» | Який формат — CSV, XLSX? З яким кодуванням? Як називається файл? | Неповнота |
| «працює швидко» | Швидко — це скільки? На якому обсязі: 100 замовлень чи 500 тисяч? | Неоднозначність |
| «усі замовлення» | А сусідня сторі каже, що менеджер бачить лише замовлення свого регіону. Експорт теж обмежений регіоном чи ні? | Суперечність |
| — | Що бачить користувач, поки файл готується? Що при помилці? | Неповнота |
| AC 2 у цілому | До «працює швидко» неможливо написати перевірку з очікуваним результатом | Тестопридатність |
Що тут важливо:
- Кожне питання — дефект, який не був написаний. Якби суперечність із регіонами дожила до тестування, переписувати довелося б вимогу, код і тест-кейси. На рефайнменті вона коштує одну репліку і пʼять хвилин обговорення.
- Тестопридатність — головний фільтр. «Працює швидко» перетворюється на «експорт 10 000 замовлень завершується не довше ніж за 30 секунд» — і тільки тепер до AC можна написати тест. Вимога, до якої не придумується перевірка, не готова за визначенням — це і є практичний сенс Definition of Ready.
- Динамічний тест цих дефектів не зловив би. Якби розробник реалізував «усі замовлення» буквально, тест-кейс, написаний із тієї самої сторі, чесно перевірив би цю поведінку і пройшов — а витік чужих даних поїхав би в прод із зеленою регресією.
Кейс 2. Рев'ю тест-кейсу колеги: що шукати і як казати
Колега приніс на рев'ю тест-кейс до того самого експорту:
Назва: Перевірити експорт
Кроки:
1. Відкрити сторінку замовлень.
2. Натиснути «Експорт».
Очікуваний результат: файл завантажився, все ок.
Це неформальне рев'ю: без протоколу, без модератора — «глянь, будь ласка». Але шукаємо ті самі класи проблем, що й у вимогах:
| Знахідка | Коментар, який працює | Коментар, який руйнує |
|---|---|---|
| Розмитий очікуваний результат | «В очікуваному результаті не видно, що саме перевіряємо: формат файлу, кількість рядків, відповідність фільтрам?» | «Все ок — це не результат» |
| Немає негативних сценаріїв | «Не бачу кейса для порожнього списку замовлень і для обриву звʼязку під час експорту — додамо?» | «Ти знову забув негативні сценарії» |
| Кроки без передумов | «У кроках не зафіксовано, під якою роллю і з якими даними стартуємо — на порожньому акаунті крок 2 поведеться інакше» | «Незрозуміло написано» |
Що тут важливо:
- Коментар — про артефакт, не про людину. Ліва колонка вказує на конкретне місце тексту і пропонує дію; права оцінює автора. Після правої колонки тест-кейси на рев'ю носити перестають — і команда втрачає найдешевший канал знаходження дефектів.
- Свіже око ловить те, що очевидно лише автору. Автор знає передумови зі свого контексту, тому в кейсі їх не записав. Рецензент контексту не має — і саме тому бачить дірку.
- Для джуна це двобічний тренажер. Коментарі до твоїх кейсів роблять їх кращими, а рев'ю чужих — найшвидший спосіб перейняти, як сеньйор структурує перевірки.
Кейс 3. Статичний аналіз: забутий await ловиться до запуску
Той самий принцип «знайти дефект без виконання», тільки виконавець — інструмент. Тест на експорт, який виглядає робочим:
import { test, expect } from '@playwright/test';
test('менеджер експортує замовлення у CSV', async ({ page }) => {
page.goto('/orders'); // забутий await: тест побіжить далі, не дочекавшись переходу
await page.getByRole('button', { name: 'Експорт' }).click();
await expect(page.getByTestId('export-status')).toHaveText('Готово');
});
Динамічно цей дефект проявиться як флакі-тест: коли сторінка встигає завантажитися до кліку — зелений, коли ні — червоний. Причину такого «падає через раз» шукають годинами, бо симптом залежить від таймінгів, а не від коду, що на екрані.
Статично його ловить правило лінтера, ще до першого запуску:
error: Promises must be awaited, end with a call to .catch, ...
@typescript-eslint/no-floating-promises
4:3 page.goto('/orders');
Що тут важливо:
- Той самий дефект: секунда замість години. Рядок підкреслено прямо в редакторі — не треба ні білда, ні прогону, ні розбору флаку в CI. Це найкоротша ілюстрація економіки статичного тестування.
- Лінтер і перевірка типів мають стояти воротами в пайплайні. Код, який не проходить
eslintіtsc, не потрапляє в основну гілку — тоді цілий клас дефектів тестового коду вимирає ще до код-рев'ю, а люди на рев'ю витрачають час на логіку, а не на пошук забутихawait. - Межа інструмента. Лінтер зловить забутий
await, але не помітить, що асерт перевіряє не той інваріант — наприклад, що тест дивиться на статус, а мав би перевіряти вміст файлу. Форму перевіряє машина, поведінку і намір — люди на рев'ю.
Статичне vs динамічне
- Можу дати означення: статичне тестування — перевірка робочих продуктів без виконання коду, читанням, обговоренням, аналізом — і тому воно доступне з першого дня проєкту, коли динамічному ще нічого запускати.
- Знаю різницю дефект (defect) vs відмова (failure): статика знаходить дефект напряму, динаміка бачить відмову, від якої до дефекту ще треба дійти дебагом.
- Можу назвати дефекти, які ловляться лише статикою (суперечність вимог, пропущена вимога, недосяжний код, невикористана змінна), і лише динамікою (швидкодія під навантаженням, живі інтеграції, памʼять) — тому підходи доповнюють одне одного, а «ретельне рев'ю — тестувати не треба» хибне в обидва боки.
Обʼєкти статичного тестування
- Можу перелічити робочі продукти для рев'ю: вимоги/user story/AC, архітектура і дизайн, код, тестові артефакти, документація і конфіги — і пояснити, чому вимоги найвигідніший обʼєкт: дефект у них ще нічого не коштує виправити.
- Памʼятаю, що рев'ю тест-кейсів — теж статичне тестування, і чому воно двічі корисне для джуна.
Типи рев'ю і процес
- Знаю чотири типи рев'ю за зростанням формальності: неформальне → walkthrough → технічне рев'ю → інспекція.
- Памʼятаю три осі відмінності між типами: хто веде, чи обовʼязкова індивідуальна підготовка, наскільки задокументований результат.
- Можу пояснити різницю walkthrough vs інспекція: автор і спільне розуміння проти фасилітатора, формального процесу і максимуму дефектів.
- Знаю, що технічне рев'ю веде фасилітатор, рецензенти — технічні експерти, підготовка обовʼязкова, ціль — консенсус і технічне рішення.
- Можу назвати ролі формального рев'ю: автор, модератор/фасилітатор, секретар (scribe), рецензенти, менеджер — і що в інспекції автор не буває модератором чи секретарем.
- Знаю пʼять активностей процесу рев'ю (планування → ініціація → індивідуальне рев'ю → обговорення знахідок → виправлення і звітування) і чому найбільше дефектів дає саме індивідуальне рев'ю.
- Можу сказати, куди на шкалі потрапляє код-рев'ю в PR (неформальне, іноді з елементами технічного) і де досі живуть формальні інспекції (регульовані домени).
Статичний аналіз
- Знаю різницю рев'ю vs статичний аналіз: рев'ю виконують люди, аналіз — інструменти, що розбирають артефакт як структуру без виконання.
- Можу назвати класи інструментів: лінтери (ESLint), перевірка типів (
tsc), сканери безпеки й залежностей, аналізатори складності (SonarQube). - Можу розповісти кейс із забутим
awaitу Playwright: динамічно — флакі-тест і години дебагу, статично — правилоno-floating-promisesпідкреслює рядок ще в редакторі. - Памʼятаю межу статичного аналізу: він бачить форму, а не поведінку — зелений лінтер не означає, що тест перевіряє правильний інваріант.
Економіка і роль QA
- Можу навести три причини дешевизни статики: не потрібна інфраструктура, дефект знаходиться напряму, ловиться те, чого динаміка не побачить ніколи.
- Можу пояснити, чому дефект у самій вимозі динамічний тест пропустить: тест перевіряє код проти вимоги і чесно пройде, перевіривши неправильну поведінку.
- Знаю чотири класи дефектів вимог, які шукає QA: неоднозначність, неповнота, суперечності, тестопридатність (testability) — і звʼязок останньої з Definition of Ready: вимога без придуманої перевірки з очікуваним результатом не готова.
- Памʼятаю правило гігієни рев'ю: коментар — про артефакт, а не про людину, інакше драфти на рев'ю носити перестануть.
Що таке статичне тестування?
Питання
Означення статичного тестування (static testing) — і чому воно доступне з першого дня проєкту?