“Критичні гілки” — це місця в коді, де помилка коштує дорого: витік даних, неправильні права доступу, поламані стани документів/публікацій, дублікати через черги, неконсистентні записи через транзакції, або тихі збої, які не видно одразу. Покриття тестами критичних гілок — це не про відсоток coverage. Це про гарантії: ви змінюєте код і точно знаєте, що не зламали те, що тримає систему.
Перший крок — навчитися визначати, що є критичним. Критичне там, де є “if/else” з різними бізнес-наслідками або різними правами. Наприклад: користувач може/не може редагувати; документ posted/не posted; новина published/не published; платіж рознесений/не рознесений; файл валідний/невалідний; job успішна/failed; кеш оновився/ні. Якщо різниця між гілками впливає на гроші, доступи, публічний контент або цілісність даних — це критична гілка.
Далі — що тестувати в першу чергу. Є шість категорій, які майже завжди критичні у ваших сценаріях (CMS + адмінка + модулі обліку).
Перша категорія: доступи й видимість. Це найважливіше. Тести мають гарантувати, що роль без прав не бачить/не може робити. Причому не тільки “403 на кнопці”, а й “навіть якщо підставити URL або параметри фільтрів, дані не витечуть”. Тут критичні гілки: автор vs редактор vs адмін; “бачить тільки своє” vs “бачить ресурс” vs “бачить все”; “можна редагувати” тільки в draft, але не в published/posted.
Друга категорія: переходи станів (state machine). Будь-яка система зі статусами має “правильні” переходи і “заборонені”. Критична гілка — це перевірка: можна/не можна перейти. Приклад для CMS: draft → review → published, але published → draft заборонено або потребує окремої дії. Для документів: draft → posted, але posted → update сум заборонено. Тести мають закривати: дозволений перехід працює, заборонений — дає помилку і не змінює БД.
Третя категорія: валідація та інваріанти даних. Це гілки “дані валідні/невалідні”. Критично тестувати не тільки “порожній заголовок”, а й бізнес-інваріанти: унікальність номера, обов’язковість складу при track_stock, валюта/курс, дата в межах, slug не пустий для публікації, суми не від’ємні, зв’язки існують. Тест має гарантувати: при невалідних даних запис не створюється/не змінюється, і користувач отримує прогнозовану відповідь (errors/422).
Четверта категорія: транзакції й консистентність. Критична гілка — “успіх усіх кроків” vs “помилка на середині”. Якщо сервіс пише в 2+ таблиці, вам потрібен тест, що при помилці нічого не “напівзаписалося”. Це особливо важливо для фінансових документів, рознесення, складських рухів, а в CMS — для зв’язок типу “новина + медіа + теги + activity”. Тестовий сценарій: штучно зламати один крок (наприклад, кинути виняток) і перевірити, що в БД немає часткових слідів.
П’ята категорія: фільтри/пошук/пагінація, які керують видимістю. Тут критичні гілки — “фільтр застосувався” і “фільтр не зламав доступ”. Тести мають гарантувати, що фільтри не розширюють доступ, що date_from/date_to працюють коректно по межах дня, що статуси обмежені whitelist-ом, що пагінація зберігає query string.
Шоста категорія: асинхронщина (queues) і побічні ефекти. Критичні гілки — “job повторився” і “job впав”. Ви маєте тестувати ідемпотентність (щоб retry не створив дубль нотифікацій/постів/файлів), і тестувати фіксацію failure-стану (статус failed + причина). Для навчання достатньо кількох тестів на найважливіші jobs: наприклад, “відправка нотифікації не дублюється при повторі”, “обробка медіа ставить failed при невалідному файлі”.
Як саме будувати тести, щоб вони були про “гілки”, а не про косметику. Гілка завжди має спостережуваний результат: статус-код, зміна полів у БД, створення/відсутність записів, зміна статусу, поява activity, запуск job. Тест повинен перевіряти результат, а не внутрішню реалізацію. Не треба тестувати “викликався метод приватний X”. Треба тестувати: “після цієї дії стан такий, доступ такий, записи в БД такі”.
Пріоритети в навчанні (щоб не розмазуватися). Для кожного модуля спочатку робите 5–8 feature-тестів “щитів”: доступи, дозволений/заборонений перехід статусу, валідація, один тест на транзакцію, один тест на фільтр, один тест на пагінацію. Потім — один-два тести на edge-case, який найбільш імовірний у вашому домені (наприклад, “posted не редагується”, “published без slug заборонено”). Це дає вам кістяк без перевантаження.
Типові помилки при покритті критичних гілок. Перша — тести лише на “happy path”. Вони не ловлять пожежі. Друга — тести, що відключають middleware або обходять policy — вони не захищають від витоків. Третя — надто крихкі тести, які перевіряють HTML до коми; такі тести падають від верстки, а не від логіки. Четверта — тести без контрольних даних (коли ви не впевнені, що саме повинно бути у вибірці). Критичні тести мають бути максимально детермінованими.
Висновок: покриття критичних гілок — це створення “страхової сітки” навколо того, що тримає систему: доступи, переходи станів, валідація/інваріанти, транзакції, фільтри, та асинхронні побічні ефекти. Якщо ви навчитеся спочатку покривати саме ці гілки, то будь-який наступний рефакторинг (partials/components/services) стає безпечним: ви міняєте код і точно знаєте, що не відкрили дані, не зламали статуси і не зробили дублікатів.