GH GambleHub

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

ЗавданняТипЧому
Чиста бізнес-логіка (валідації, розрахунки комісій, ідемпотентність ключів)UnitШвидко, детерміновано, багато граничних значень
Маппінги DTO↔model, серіалізація, парсингUnitБагато кейсів, легко ізолювати
Репозиторії/ORM-запитиIntegration (с test DB)«Поведінку» ORM і SQL нюанси видно тільки на живій БД
HTTP-контракт (статуси, заголовки, схеми)Integration / ContractПотрібен живий стек HTTP + JSON Schema/OpenAPI
Saga/Outbox, ретраї, дедлайниIntegration / ComponentТаймінги, транзакційність, брокер
Rate limit в gatewayIntegrationRedis/стейт/таймаути
Платіжні вебхуки (HMAC, повтор)Integration / CDCПідписи, годинники, мережеві особливості

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 - паралелити по контейнерах/портах; використовувати міграції на запуску.

Flaky-антидот:
  • контрольований час (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.

Приклад матриці (GitHub Actions, фрагмент):
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. Особливо перевірте платіжні/вебхук-шляхи: підписи, ретраї та ідемпотентність.

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.