Популярний спосіб масштабування у сучасних ІТ відбувається шляхом перерозподілу робіт по проекту, серед різних команд (розподілених команд). Ці команди, незаважаючи одна-одній, паралельно створюють кожен окремий функціонал, а згодом інтегрують його у цілісну систему. Розділення системи на множину сервісів, означає що ці сервіси обов’язково повинні взаємодіяти один з одним через чітко визначені інтерфейси.

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

  • REST і JSON через HTTPS;
  • RPC;
  • побудова на основі архітектури орієнтованої на подій з використанням черг.

Кожен інтерфейс задіює дві сторони: постачальника і споживача.

Постачальник надає дані споживачам. Споживач обробляє дані, отримані від постачальника.

У світі REST постачальник створює REST API з усіма необхідними кінцевими точками, а споживач звертається (звертається) до цього REST API, щоб отримати дані або ініціювати зміни в іншій службі. В асинхронному світі подієво-орієнтованої архітектури постачальник (часто іменований видавцем) продукує дані в чергу; а споживач (підписник) підписується на ці черги, зчитує і обробляє дані. Оскільки сервіси постачальника і споживача розподіляються по різних командах, отже, складається ситуація, коли потрібно чітко вказати інтерфейс між ними (так званий контракт). Традиційно компанії підходять до цього механізму наступним чином:

  1. Пишуть довгу і детальну специфікацію інтерфейсу (контракт).
  2. Реалізовують сервіс постачальника згідно з певним контрактом.
  3. Передають специфікації інтерфейсу стороні споживача.
  4. Виникає очікування, доки вони реалізують свою частину інтерфейсу.
  5. Проведення тестування, щоб все перевірити.
  6. Сподіватися, що обидві команди будуть завжди дотримуватися визначеного інтерфейсу.

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

Що таке CDC (Consumer Driven Contracts)?

Три ключові елементи:

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

Таким чином, контракт — виконуваний. І основна особливість підходу полягає в тому, що вимоги до поведінки API йдуть upstream, від клієнта до сервера.

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

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

  • поліпшення комунікації;
  • поділу спільного розуміння проблемної області;
  • реалізації рішення всередині і між командами.

Орієнтовані на користувача контрактні тести (CDC-тести) дозволяють споживачам управляти реалізацією контракту. За допомогою CDC споживачі пишуть тести, які перевіряють інтерфейс для всіх даних, які їм потрібні. Потім команда публікує ці тести, щоб розробники служби постачальника могли легко могли отримати і запустити ці тести. Тепер вони можуть розробити свій API, запустивши тести CDC. Після прогону всіх тестів вони знають, що задовольнили всі потреби команди на стороні споживача. Такий підхід дозволяє команді постачальника інтерфейсу реалізувати тільки те, що дійсно необхідно.

Команда постачальника повинна безперервно отримувати і виконувати ці CDC-тести (у своїй збірці), щоб негайно помічати будь-які критичні зміни. Якщо вони порушують інтерфейс, то їх CDC-тести не пройдуть, запобігаючи критичні зміни. Доки тести раняться, команда може вносити будь-які зміни, які забажає, не турбуючись про інші команди. Орієнтований на споживача контрактний підхід скорочує процес розробки до наступного:

  • Команда споживача пише автоматизовані тести з усіма очікуваннями з боку споживачів.
  • Вони публікують тести для команди постачальника.
  • Команда постачальника безперервно запускає CDC-тести і стежить за ними.
  • Команди негайно вступають в переговори, коли CDC-тести ламаються.

Якщо ваша організація запровадить підхід мікросервісов, то проведення CDC-тестів — важливий крок до створення автономних груп. CDC-тести — це автоматизований спосіб координації в колективі. Тести гарантують, що інтерфейси між командами робочі. Невдалий CDC-тест — хороший привід піти до постраждалої команді, поговорити про майбутні зміни API і з’ясувати, куди рухатися далі.

В останні роки підхід CDC стає більш популярним і створено кілька інструментів для спрощення написання і обміну тестами.

Pact, ймовірно, найвідоміший серед них. Він пропонує витончений підхід до написання тестів для споживача і постачальника, надає заглушки для окремих служб і дозволяє обмінюватися CDC-тестами з іншими командами. Pact портовано на безліч платформ і може використовуватися з мовами JVM, Ruby, .NET, JavaScript і багатьма іншими. Pact — розумний вибір, щоб розпочати роботу з CDC. Документація допомагає отримати розуміння CDC, що в свою чергу полегшує робить цілком зрозумілою роботу з іншими командами. Орієнтовані на користувача контрактні тести можуть кардинально спростити роботу автономних команд, які почнуть діяти швидко і впевнено. Якісний набір CDC-тестів неоціненний, щоб швидко продовжувати розробку, не ламаючи сусідні сервіси і не засмучуючи тим самим інші команди.

Застосування CDC

Які обмеження існують у Consumer Driven Contracts?

  • За використання такого підходу доводиться платити додатковими інструментами на кшталт Pact. Самі по собі контракти — це додатковий артефакт, ще одна абстракція, яку потрібно акуратно підтримувати, усвідомлено застосовувати до неї інженерні практики.
  • Вони не замінюють e2e тести, так як заглушки все одно залишаються заглушками – моделями реальних компонентів системи, які може і чуть-чуть, але не відповідають дійсності. Через них не перевірити складні сценарії.
  • Також CDC не замінюють функціональні тести API. Тести дорожчі в підтримці, ніж  Unit Tests. Розробники Pact рекомендують користуватися наступною евристикою — якщо прибрати контракт і це не викличе помилки або неправильну інтерпретацію з боку клієнта — значить він не потрібен. Наприклад, не потрібно через контракт описувати абсолютно всі коди помилок API, якщо клієнт обробляє їх однаково. Іншими словами, договір визначає для сервісу тільки те, що важливо його клієнту. Не більше, але й не менше.

Занадто велика кількість контрактів також ускладнює еволюцію API. Кожен додатковий контракт — це привід для червоних тестів. Потрібно проектувати CDC таким чином, щоб кожен fail тесту ніс собою корисне смислове навантаження, яке переважує вартість його підтримки.

Підсумок

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

В той же час, інструменти і фреймворки CDC активно розробляються і вже досягли зрілості. Звичайно, для кращого розуміння потрібні приклади.

Запрошуємо на цікавий Вебінар із госткм з-за кордону, де Ви зможете детальніше дізнатись про Контрактне Тестування і Тестування Мікросервісів 🙂 Підписуйтесь на наш YouTube щоб не пропустити цікаві та корисні події 🔔

Related posts

Leave a Comment

Цей сайт використовує Akismet для зменшення спаму. Дізнайтеся, як обробляються ваші дані коментарів.