Unit vs Integration тести
1) Навіщо розрізняти типи тестів
Правильна грануляція тестів робить розробку передбачуваною: Unit ловлять дефекти логіки швидко і дешево; Integration перевіряють зв'язки модулів, реальний транспорт і «клей». Разом вони зменшують регрес і прискорюють релізи.
2) Визначення та межі
Unit-тест
Перевіряє малу одиницю поведінки (функцію, клас, use-case) в ізоляції.
Зовнішні залежності замінені (mock/stub/fake).
Швидкий (мс-десятки мс), детермінований.
Integration-тест
Перевіряє взаємодію декількох реальних компонентів: БД, брокер (Kafka/RabbitMQ), HTTP/gRPC, файлова система, кеш.
Мінімум моків, реальні протоколи.
Повільніше (сотні мс-секунди), дорожче за підтримкою.
3) Піраміда тестування (а не крижаний ріжок)
Підстава: Unit (70-80% за кількістю) - дешево, швидко.
Середній шар: Integration/Component (15-25%) - критичні шляхи і контракти.
Верх: E2E/UX/Exploratory (5-10%) - мінімально достатньо.
З боків: Static Analysis/Lint/Type check і Mutation testing як підсилювачі якості.
4) Що віддавати Unit, а що - Integration
5) Дані та фікстури
Unit
Inline фікстури/білдери (factory methods).
Табличні тести (table-driven) для граничних значень.
Property-based підхід для інваріантів (наприклад, «сума дебетів = сумі кредитів»).
Integration
Hermetic оточення: Testcontainers/Docker Compose поднимают `postgres + redis + kafka + wiremock`.
Початковий seed в БД/кеші і очищення після (транзакція/rollback, truncate).
Годинник/таймери - фейкові (контрольовані), інакше флаки.
6) Інструменти та патерни
Mocks/Stubs/Fakes/Spies:- Stub - фіксована відповідь (дешево).
- Mock - перевірка взаємодій/кількості викликів.
- Fake - спрощена реалізація (наприклад, In-Memory Repo).
- Contract testing (CDC): Pact/Swagger-based - фіксуємо очікування клієнта і перевіряємо провайдера.
- WireMock/MockServer - HTTP-заглушки для сторонніх сервісів.
- Testcontainers - живі БД/брокери локально і в CI без «зоопарку».
7) Приклади
7. 1 Unit: ідемпотентність платежу (pseudocode)
python def test_idempotent_create_payment_returns_same_id():
repo = InMemoryPayments()
service = Payments(repo)
first = service. create(amount=100, key="abc")
second = service. create(amount=100, key="abc")
assert first. id == second. id assert repo. count() == 1
7. 2 Integration: підпис вебхука (HMAC) + повтор
bash docker-compose: app + redis + wiremock (PSP)
docker compose -f docker-compose. test. yml up -d pytest -m "integration and webhook" -q
Тест:
- WireMock віддає подію з'X-Timestamp'і підписом.
- Програма перевіряє HMAC, дедупліціює по'event _ id', повтор через 5 сек не створює дубль.
- Перевіряємо «200» і, що запис один.
7. 3 CDC: контракт клієнта до провайдера
Клієнт формує Pact (очікування: 'POST/v1/payout'→'201'зі схемою).
Провайдер в CI проганяє верифікацію контракту на своєму стенді.
8) Швидкість, паралельність, флейки
Unit повинні працювати <100 мс на тест; пакет - секунди.
Integration - паралелити по контейнерах/портах; використовувати міграції на запуску.
- контрольований час (fake clock),
- очікування «по явному події», а не'sleep',
- стабільні пороги (ретраї з джиттером тестувати детерміновано).
9) Метрики якості
Coverage (рядки/гілки): корисно для спостереження тренда, але не мета.
Mutation testing (PIT/Mutmut): показує, чи «вбивають» тести помилкові зміни - реальна сила асуренса.
Test duration и flaky rate: алерти при зростанні.
Defect containment: частка багів, перехоплених до продакшену.
10) Вбудовування в CI/CD
Джоби: unit → integration → e2e (fan-out за сервісами).
Кеш залежностей, паралельні матриці з БД/мов/версій.
Звіти: JUnit/Allure + артефакти логів контейнерів (при падіннях).
Gate: «зелені unit + критичні integration» - умова мержа; e2e - на nightly.
yaml strategy:
matrix:
db: [postgres14, postgres16]
steps:
- run: docker run -d --name db -e POSTGRES_PASSWORD=pw postgres:${{ matrix. db }}
- run: pytest -m "unit" -q
- run: pytest -m "integration" -q
11) Мікросервіси та події
Сервісні контракти: OpenAPI/Protobuf версіонуються; тести на сумісність (backward).
Event-driven:- Unit: маппінг доменних подій та інваріанти.
- Integration: публікація/підписка в реальному брокері (Kafka), outbox/inbox семантика, exactly-once імітація (принаймні - idempotent).
- Тести ретраїв/дублікатів/перевпорядкування (out-of-order).
12) Дані та ізоляція в Integration
Кожен тест → унікальна схема/БД (Testcontainers JDBC URL'? TC _ TMPFS =/var/lib/postgresql/data:rw`).
Транзакційні фікстури (begin→run→rollback) прискорюють чистку.
Для Redis/кешу - ключовий префікс'test:${RUN_ID}:` и `FLUSHDB` в teardown.
13) Специфіка iGaming/фінансів
Гроші та ліміти: property-based тести на інваріанти (баланс ≥ 0, сумарні обмеження).
Регуляторика: перевірка журналювання (аудит-лог пишеться), незмінні події.
Платежі/PSP: інтеграційні тести HMAC/mTLS,'Retry-After', ідемпотентність, дедуп'jti'.
Відповідальна гра: тести правил порогів/кулдаунів; «vchera→segodnya» на fake clock.
14) Антипатерни
«Unit», які піднімають БД/НТТР - це вже integration (плутають шари і уповільнюють CI).
Високий coverage за рахунок порожніх тверджень («покрили, але не перевірили»).
Моки логіки сторонніх сервісів там, де потрібен контракт (ламається при оновленні).
Тести з'sleep (5)'замість очікувань події/умови.
Загальна тестова БД для паралельних тестів → гонки і флейки.
15) Чек-лист prod-готовності
- Піраміда визначена: % часткою Unit/Integration/E2E і цілі за часом прогону.
- Unit ізольовані, швидкі, покривають граничні значення та інваріанти.
- Integration використовують hermetic-оточення (Testcontainers/Compose), без загальних стейтів.
- Контрактні тести (OpenAPI/Pact) верифікуються в CI.
- Дані тестів - керовані: seed/rollback/префікси, fake clock.
- Паралельний прогін, звіти JUnit/Allure, артефакти логів контейнерів.
- Метрики: duration, flaky rate, mutation score; алерти на деградацію.
- Платіжні/вебхук-сценарії: HMAC/mTLS, ретраї, ідемпотентність, дедуп.
- Документація стратегії та приклади шаблонів тестів.
16) TL; DR
Unit - максимум логіки, мінімум оточення; Integration - мінімум моків, максимум реалізму. Тримайте піраміду: швидкі Unit ловлять 80% дефектів, Integration підтверджують зв'язки і контракти. Використовуйте hermetic-контейнери, контрактні тести, fake clock і паралельність. Міряйте не тільки coverage, але і mutation score і flaky rate. Особливо перевірте платіжні/вебхук-шляхи: підписи, ретраї та ідемпотентність.