Что такое контрактное тестирование?

Consumer Contract Testing
Плюсы одной картинкой

Это вид интеграционного тестирования

Контрактное тестирование является специфическим подвидом интеграционного тестирования — проверки целостности системы, состоящей из модулей и компонентов (уже проверенных на предварительных этапах цикла). 

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

В современной разработке становится общепринятым подход «сквозного интеграционного», подразумевающий одновременное развертывание всех компонентов системы в реальном прод-окружении, и соответственно тестирование интеграции этих компонентов. Путем выполнения (очень) большого количества сквозных е2е тестовых сценариев, имитирующих «путь пользователя по приложению». Такой подход не все одобряют, считая е2е интеграционные тесты плохой практикой тестирования.

Почему сквозные тесты часто проблемные

Они должны имитировать поведение конечного пользователя и в принципе неплохо справляются с этой задачей, но посмотрите:

  • Они всегда медленные. Это понятно, тестировать извилистый путь по множеству подсистем, в таком пути всегда будет много «непредвиденных остановок». Тесты могут выполняться очень долго по меркам привыкших к юнит-тестам — порядка минуты или даже больше. Есть проблемы с тестовыми данными и их подготовкой, обработкой, настройкой и запуском тестовых окружений и так далее.
  • Сложно поддерживать. Такие тесты требуют, чтобы все подсистемы были ОК
  • Уже из перечисленного понятно, что е2е интеграционные тесты могут быть нестабильными. Чаще всего они показывают ложнопозитивный результат из-за проблем с тестовыми окружениями, их конфигурациями. Флейки-тесты забирают время у QA-команды. 
  • Сложно фиксить. Найти причину бага всегда сложно — системы сложные, распределенные.
  • Плохо масштабируются. Процесс разработки идет, продукт укрупняется, все объекты в нем усложняются, становится все больше тестов, тест-сьюты все медленнее, в результате релизы задерживаются.
  • Дефекты начинают убирать слишком поздно в цикле. Сьюты сложные и медленные, их запускают в CI, и это делает другая команда много дней спустя, когда разработчики уже всё забыли. Такая длинная петля фидбека — это не ОК, это очень дорого, и это «не по эджайлу».

Поэтому сквозные интеграционные многими считаются в общем виде плохой практикой, они рекомендуют свести такие тесты к минимуму: только покрытие ключевых бизнес-транзакций и базовых функций интерфейса.

Контрактное тестирование — это

Это методология проверки, что две подсистемы (чаще всего два микросервиса) совместимы и могут беспроблемно коммуницировать. Суть в том, что взаимодействия, которые происходят между двумя сервисами, записываются, «сохраняются как контракт», который затем используется как «доказательство», что обе «стороны контракта» соблюдают обязательства. Контрактное тестирование выходит за рамки тестирования схем (schema testing), поскольку требует от обеих сторон прийти к консенсусу относительно минимального набора взаимодействий; и позволяя такому «контракту» развиваться, эволюционировать со временем.

От других форм (подтипов) интеграционного тестирования контрактное отличается также тем, что каждая система может быть протестирована независимо, а также тем, что контракт генерируется самим кодом, и значит всегда поддерживается в актуальном состоянии.

На диаграмме показаны этапы контрактного тестирования:

CDC steps
Этапы контрактного тестирования

Consumer-driving контрактное тестирование

Consumer Driven Contract (CDC). Название означает просто подход с бОльшим участием «принимающей запрос стороны» в тестировании, чем это обычно принято; то есть улучшение дизайна микросервисов через размещение потребителей запросов (клиентов) API как бы в центр процессов интеграционного тестирования. Подход c бОльшим вниманием к «отдающей запросы» стороне API имеет свои недостатки, которые контрактное тестирование пытается исправить.

Существуют компании, специализирующиеся на таком типе тестирования, например Spring Cloud Contracts и PactFlow

В чем преимущества контрактного тестирования

Рассмотрим контрактное тестирование в более широком контексте. При разработке стратегии тестирования (подробнее?) хорошей практикой является соблюдение принципа «тестовой пирамиды».

Пирамида тестов современного сложного приложения
Современная тестовая пирамида

Как писал автор этой концепции Майкл Кон:

«Соблюдайте принцип, и тесты будут правильными, быстрыми, и легкими в обслуживании. Пишите маленькие и быстрые юнит-тесты. Чем ближе к концу цикла, тем больше по размеру тесты, и тем меньше их должно быть.»

Пирамида тестирования Майкла Кона
Правильная тестовая пирамида, как ее изобразил сам автор концепции. У Кона «UI-тесты» это то же что e2e-тесты.

Контрактные тесты находятся в средней части пирамиды, на «сервисном» уровне; они должны быть достаточно быстрыми, и не очень большими, как бы золотой серединой. Задача контрактных тестов: обеспечить, чтобы интегрируемые системы были совместимы с остальным релизным кодом. 

Контрактные тесты, если выполнены правильно, имеют характеристики, резко отличающие их от интегрированных e2e-тестов (примечание: разницу между интеграционными и интегрированными тестами, с точки зрения компании Spotify, можно увидеть здесь).

Итак, характеристики контрактных тестов:

  • Они быстрые: им не нужно связываться с другими многочисленными системами
  • Они просты в поддержке и обслуживании. Всю систему знать/понимать не обязательно
  • Они просты для дебага и корректировки: проблемы могут быть только в тестируемом компоненте; ты просто видишь список проблемных API-эндойнтов с которым далее работаешь
  • Они хорошо воспроизводимы
  • Масштабируемы, поскольку каждый компонент может быть тестирован отдельно; билд-пайплайны не разбухают экспоненциально
  • Они позволяют вскрыть баги локально на машине разработчика/тестировщика

С бизнес-точки зрения, давно и хорошо известно, что чем позже найден баг, тем дороже он обходится.

Вред от багов увеличивается со временем
Вред от багов увеличивается со временем

Если большинство тестов на проекте составляют маленькие быстрые юнит- или локальные интеграционные тесты, можно удержать «пирамиду» в правильном состоянии.

Еще плюсы контрактных тестов:

  • Дает возможность разрабатывать потребительскую часть приложения (например React Web App) до разработки API
  • Возможность сначала получить/уточнить требования к стороне-провайдеру, поэтому они имплементируются точнее
  • Получают хорошо документированные use-кейсы, точнее показывающие использование API-провайдера
  • Точнее видимость, в каких областях нужно проработать запрос, с точки зрения принимающей стороны, удаляя неиспользуемые вещи и добавляя часто используемые
  • Быстрее определение ошибок на принимающей стороне, при изменениях в API со стороны провайдера

Разумеется, контрактное тестирование не является панацеей от всех проблем в интеграционном тестировании; все зависит от проекта и от выбранной стратегии.

Подробнее о контрактном тестировании (микросервисов)

Итак, мы уже знаем, что контрактное тестирование должно проверять/верифицировать качество коммуникации сервисов между собой. Также знаем, что есть две стороны в таком тестировании: потребителя (Consumer, или принимающая сторона упомянутая выше) и поставщика (Supplier, Provider, выше также называемого провайдером). Потребитель использует сервис, провайдер предоставляет. Примером может служить фронтенд-сервис + бекенд-сервис, или же два бекенд-сервиса, интегрированные между собой.

Итак, контрактные тесты проверяют исполнение контракта по качеству вызова сервиса.

Но не обязательно точность данных. Например стаб снимает снепшот состояния в определенное время, проверяя только правильность формата данных (а не сами данные). Контрактный тест проверяет, что формат остается правильным (а сами данные могут быть некорректными, это не совсем предмет исследования).

Итак, паттерн CDC-контрактов на практике чаще всего применим для коррекции возникающих (или предполагаемых) проблем с деплоем, путем интеграции CDC в CI/CD-пайплайн (здесь подробнее о CI/CD).

Источники: 1,2,3

***

Дополнительное по теме:

Тестирование API и

Вопросы на собеседовании по тестированию API, а также

Канал об автоматизации QA

Какой была ваша первая зарплата в QA и как вы искали первую работу?

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии

Мы в Telegram

Наш официальный канал
Полезные материалы и тесты
Готовимся к собеседованию
Project- и Product-менеджмент

? Популярное

? Telegram-обсуждения

Наши подписчики обсуждают, как искали первую работу в QA. Некоторые ищут ее прямо сейчас.
Наши подписчики рассказывают о том, как не бояться задавать тупые вопросы и чувствовать себя уверенно в новой команде.
Обсуждаем, куда лучше податься - в менеджмент или по технической ветке?
Говорим о конфликтных ситуациях в команде и о том, как их избежать
$1100*
медианная зарплата в QA в июне 2023

*по результатам опроса QA-инженеров в нашем телеграм-канале

Собеседование

19%*
IT-специалистов переехало или приняло решение о переезде из России по состоянию на конец марта 2022

*по результатам опроса в нашем телеграм-канале

live

Обсуждают сейчас