Впровадження Pact Contract Testing у CI/CD для мікросервісів

Мікросервіси найчастіше ламаються на стиках: оновили один сервіс — упали сусідні. Ми впроваджуємо контрактне тестування в процес випуску під ключ: перевірки сумісності запускаються автоматично до релізу й відсікають несумісні версії. Результат — менше аварій на інтеграціях і строк випуску в рази коротший.
Часті запитання

Контрактне тестування: де рвуться інтеграції мікросервісів

Мікросервіси випускаються незалежно: у кожного зелений набір власних тестів, збірка проходить без зауважень, а на інтеграційному стенді розвалюється стик.

Один сервіс чекає поле обов'язковим, інший віддає його порожнім; постачальник змінив код відповіді на помилку — споживач вважає це успіхом і записує биті дані у свою базу.

Несумісність інтерфейсів майже ніколи не виглядає як явна поломка. Перейменоване поле, змінений формат дати, новий обов'язковий параметр у запиті, зміна типу значення — окремо кожен сервіс залишається працездатним, а зв'язка перестає працювати.

Внутрішні тести такого не спіймають: вони перевіряють логіку всередині сервісу і працюють на заглушках, які пише та сама команда, що й сам сервіс.

Вузьке місце інтеграції зміщується до релізу: помилку ловить не той, хто її вніс, а черговий на стенді або підтримка вже після викочення. Ціна — регрес після релізу, відкат, ручний прогін сценаріїв і зайві узгодження між командами замість однієї перевірки на вході.

Розбираємо, як це закривається контрактним тестуванням: домовленість про стики фіксується як перевірюваний артефакт у репозиторії, обидві сторони проганяються проти нього до збірки, і розходження спливає в момент правки, а не за тиждень на стику сервісів.

Вимірюваний ефект: менше відмов на стиках сервісів

Перевірки сумісності переносять розходження із середовища експлуатації на етап збірки. Поки контракт між сервісами живе в листуванні, несумісність виявляється вже в роботі: тести всередині кожного сервісу зелені, а на стику ламається формат поля або код відповіді.

Після підключення перевірок до конвеєра збірки несумісна версія до середовища не доходить — збірка зупиняється на кроці верифікації, і автор зміни одразу бачить, яка умова розійшлася з очікуванням споживача.

Ефект видно в перші тижні. Частка відмов на стиках падає до поодиноких випадків — залишаються сценарії, яких немає в контракті, і їх закривають окремими перевірками.

Швидкість випуску зростає: узгодження форматів перестає бути листуванням між командами, контракт лежить у репозиторії і перевіряється автоматично. Простій сервісів скорочується, бо інтеграційна поломка перестає бути сюрпризом релізу.

Третій ефект — час відновлення. Інцидент на стику раніше означав або відкат релізу, або спільне налагодження двох команд, поки частина функціональності недоступна.

За версіонованих контрактів несумісність підтверджується до викладки, а виправлення приходить однією зміною з обох сторін — відновлення займає один цикл збірки замість серії узгоджень.

Перевірки будуємо на Pact: двостороння верифікація підтверджує, що постачальник виконує очікування споживачів, а споживач перевіряється проти реальної поведінки. Побічний результат — контракт стає документацією стику, за якою в сервіс входить нова людина.

Варіанти перевірок: контрактне тестування та альтернативи

Перевіряти стики між сервісами можна чотирма способами, і вибір визначає, наскільки рано знаходиться дефект і скільки коштує його виправлення.

Нижче — реальні альтернативи, між якими обирають команди: від ручних обмінів до формальних контрактів, зафіксованих окремим артефактом з версією.

Різниця між ними — у точці перевірки та ціні прогону. Ручна перевірка і спільний стенд валідують систему цілком, але пізно й дорого: дефект спливає вже на етапі приймання.

Заглушки дають швидкість, але розходяться з реальною поведінкою сервісу, а контракт перевіряє стик до релізу і не вимагає піднімати все оточення.

Варіант Коли підходить Обмеження підходу
Ручна перевірка стиків Разові обміни, 2-3 взаємодії, рідкісні зміни Не масштабується, результат залежить від людини, помилка доходить до проду
Наскрізні тести на спільному стенді 5-10 критичних сценаріїв, наскрізний шлях цілком Довгий прогін, стенд зайнятий однією командою, падіння будь-якого сервісу обнуляє результат
Заглушки сервісів Споживач ще в роботі, зовнішня система недоступна на стенді Заглушка описує очікування, але дрейфує від реальної відповіді без звірки
Формальні контракти Багато споживачів в одного сервісу, часті релізи Потрібно вбудувати перевірку в збірку і домовитися, хто володіє контрактом

На практиці варіанти не конкурують, а ділять зони відповідальності: контракти закривають стики між своїми сервісами, наскрізні тести залишаються для критичних шляхів, заглушки — для недоступних зовнішніх систем. Тоді обмеження кожного підходу не складаються, а перекриваються.

Порядок впровадження: від аудиту стиків до передачі команді

Впровадження контрактних перевірок — не встановлення бібліотеки, а порядок робіт, де послідовність важливіша за швидкість. Якщо одразу ввімкнути перевірки на всі стики, команда отримує лавину падінь на кожному злитті й вимикає їх.

Тому етапи впровадження йдуть від інвентаризації зв'язків до передачі: кожен залишає артефакт, на який спирається наступний.

  1. Аудит стиків. Збираємо карту викликів: хто до кого звертається, які поля реально читає споживач, де очікування розходяться з фактичною відповіддю. На виході — перелік зв'язків з пріоритетом за частотою змін і критичністю.
  2. Схема контрактів. Для кожного зв'язку фіксуємо очікування споживача: обов'язкові поля, типи, коди відповідей, поведінку при помилці. Контракти на Pact версіонуються і живуть у репозиторії сервісу-постачальника.
  3. Налаштування перевірок. Підключаємо прогін у конвеєр збірки: перевірка запускається на кожен коміт і падає до публікації артефакту. Окремо налаштовуємо вітрину, де видно, який саме стик зламано.
  4. Перевірка на стенді. Проганяємо контракти на копії бойового оточення з реальним профілем даних — так вилазять розходження, невидимі на заглушках: формати дат, порожні значення, різна обробка помилок.
  5. Розбір розходжень. Кожне падіння класифікуємо: справжня несумісність, хибне спрацювання або застаріле очікування. Хибні йдуть у налаштування, справжні — у план правок з обох сторін стику.
  6. Передача команді. Віддаємо документацію щодо зв'язків, правила зміни контрактів, регламент чергування і навчання інженерів. Далі команда править контракти сама, без нашої участі.

Частина розходжень знаходиться вже на аудиті — до першого прогону перевірок.

Артефакти впровадження: схеми стиків і правила версіонування

Впровадження контрактного тестування цінне не фактом увімкнених перевірок, а комплектом артефактів, який залишається в команди. Без нього знання тримаються на двох інженерах і розсипаються за першої ротації. Нижче — те, що ми передаємо і підтримуємо в актуальному вигляді.

  • Описи інтерфейсів за кожним споживачем: які поля сервіс віддає, які обов'язкові, що відбувається при порожній відповіді і на які коди помилок споживач має право розраховувати.
  • Схема стиків — карта «споживач → провайдер» з власниками, критичністю зв'язку і зазначенням, чий випуск блокується при падінні перевірки.
  • Правила версіонування контрактів: додавання необов'язкового поля — сумісна зміна, звуження типу або видалення поля — ламка, потребує нової версії та попередження споживачів.
  • Регламент випуску: порядок публікації версії контракту, вікно обов'язкової верифікації у провайдера і правило, за яким попередня версія споживача продовжує працювати.
  • Матриця сумісності — таблиця «версія споживача × версія провайдера» з явно позначеними допустимими і забороненими поєднаннями.
  • Інструкції для чергових: що дивитися у звіті перевірки, як відрізнити зламаний контракт від заваленого оточення і як відкотити контракт.
  • Документація щодо підключення: як завести новий сервіс, де взяти еталонні приклади і як прогнати верифікацію локально.

Комплект переживає зміну команди: новий інженер підключає сервіс за інструкцією, а не за пам'яттю колеги, і заздалегідь бачить, які зв'язки ламати не можна.

Кейс: як скоротився строк випуску після перевірок стиків

Мережа з 40+ сервісів, які шість команд випускають у своєму ритмі.

Сумісність стиків там перевірялася лише на спільному стенді, після збірки всіх компонентів разом: зміна в одному сервісі ламала споживача через день-два, коли причина вже розчинялася серед десятків правок, а винуватця шукали в листуванні між командами.

Метрики до і після

Метрика До Після
Строк випуску зміни 9–12 днів 2–3 дні
Частка відмов на стиках у загальній кількості інцидентів більше третини поодинокі випадки
Розбір інтеграційного інциденту 4–6 годин до 40 хвилин
Момент виявлення несумісності через 1–2 дні на спільному стенді на збірці, до викочення

Що зробили

Очікування споживача винесли в контракт поруч із кодом сервісу — правка публічної частини тепер видна в тій самій зміні, що й логіка. Брокер контрактів на Pact звіряє версії обох сторін і не пропускає викладку, поки хоч один споживач не підтвердив сумісність.

Спільний стенд розвантажили: наскрізні сценарії залишилися, а перевірка кожної пари переїхала в збірку.

Змістовний ефект — змінився клас відмов, що доходять до проду: несумісність версій перестали знаходити користувачі. Через пів року після впровадження частка відкатів через стик упала майже до нуля, а вивільнений час пішов на розбір функціональних дефектів, які раніше відкладали.

Що робити, якщо сервіси вже пов'язані напряму?

Прямі зв'язки сервісів уже працюють і дають результат, тому ламати їх одразу не можна: поки в системі жорсткі виклики, правка одного учасника валить сусідів.

Поступове впровадження йде не «увімкнути перевірки для всіх одразу», а по одній парі за раз — починаємо з найнавантаженішої або найчастіше змінюваної взаємодії.

Перший крок не пишуть руками. Споживача запускають у режимі запису: реальні запити й відповіді перетворюються на контракт — файл з описом того, що сервіс справді чекає від постачальника.

З Pact це робиться без правок бізнес-логіки: фіксуються лише ті поля й коди відповідей, які вже використовуються в коді.

Далі перевірка йде в режимі спостереження: контракт проганяється в конвеєрі збірки, але не блокує випуск, а підсвічує розходження. Команда бачить реальну картину сумісності версій і обсяг боргу у зв'язках, при цьому постачання не зупиняється ні на день.

Коли розходжень немає дві-три ітерації підряд, перевірку для цієї пари переводять у блокуючий режим — і повторюють цикл на наступному зв'язку. План переходу стає вимірюваним: по кожній взаємодії видно, на якому кроці вона перебуває — запис, спостереження чи блокування.

Для вже розгорнутих сервісів окремо фіксується правило зворотної сумісності: поки у постачальника є споживачі попередньої версії, контракт можна тільки розширювати — додавати поля й нові коди, але не видаляти і не змінювати сенс наявних.

Застарілі контракти позначаються і знімаються, коли останній споживач перейшов на нову версію, — так сумісність версій перестає бути домовленістю на словах.

Сумніви інженерів: сумісність версій і хибні спрацювання

Сумніви щодо впровадження майже завжди одні й ті самі: перевірки сповільнять збірку, хибні спрацювання почнуть блокувати релізи, а описів інтерфейсів у командах просто немає. Нижче — як кожен із них закривається на рівні налаштування, а не обіцянок.

Контрактні перевірки сповільнять конвеєр збірки?

Прогін контрактів іде окремим завданням паралельно з модульними тестами і займає секунди, а не хвилини. Контракт публікується один раз при зміні очікувань, далі звірка йде за вже збереженим артефактом.

Якщо збірка критична за часом, перевірку сумісності виносимо в крок перед викладкою в середовище — тоді вона гальмує тільки реліз, а не кожну гілку.

Хибні спрацювання будуть зупиняти релізи?

Спрацювання означає розходження очікувань споживача і фактичної відповіді — це сигнал, а не шум. Хибні випадки дають перевірки без версіонування контрактів, тому фіксуємо правило: звірка йде тільки з сумісними гілками контракту. Нестабільні перевірки йдуть у карантин з обов'язковим розбором, а не вимикаються мовчки.

У нас немає описів інтерфейсів — з чого починати?

Описи не потрібно писати вручну заздалегідь. Знімаємо поточну поведінку сервісів, фіксуємо її як еталон і далі змінюємо тільки там, де очікування розходяться. Так впровадження не вимагає зупиняти розробку і одразу дає видиму карту зв'язків між сервісами.

Хто відповідає за перевірки після впровадження?

Зона відповідальності ділиться: споживач описує, що йому потрібно від сусіда, постачальник — що він гарантує. Контракт живе в реєстрі, у кожного — власник з команди. Ми передаємо цей регламент разом із налаштуваннями, щоб перевірки не залишилися «нічиїми».

Що з підтримкою перевірок після передачі?

Залишається регламент змін, інструкція з розбору спрацювань і навчання чергових. Супроводжуємо перший період правок, поки команди не почнуть змінювати контракти самостійно без наших інженерів.

Обговоримо задачу: що надіслати для оцінки та плану

Щоб повернутися з оцінкою і планом, а не із загальними словами, нам потрібен мінімум вхідних даних. Чим точніші вихідні дані, тим менше припущень у схемі робіт і тим реалістичніші строки пілоту.

  • Схема сервісів: хто з ким спілкується, які виклики синхронні, які йдуть через брокер повідомлень і в якому форматі.
  • Перелік постачальників і споживачів: які контракти вже описані, а де замість них живуть ручні домовленості між командами.
  • Поточний контур збірки: де запускаються перевірки, скільки триває повний прогін, які перевірки блокують злиття гілки.
  • Приклади збоїв інтеграції: що ламалося, на якому етапі помічали, скільки часу йшло на розбір і виправлення.
  • Репозиторії та доступи: достатньо прав на читання, плюс опис оточень — тестового і передпольотного.
  • Обмеження: регламент релізів, вікна викладки, вимоги інформаційної безпеки та регуляторів.
  • Що вважаємо результатом пілоту: які сервіси включаємо першими, які команди в контурі, до якого строку чекаємо ефект.

Далі ми збираємо це в схему робіт: порядок підключення сервісів, точки перевірки в конвеєрі, ролі учасників і режим відкату, якщо перевірки почнуть блокувати викладку.

Опишіть задачу — надішліть те, що є: навіть частковий набір вихідних даних дозволить повернутися з оцінкою і планом пілоту, а решту уточнимо на розборі.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139