Введение в тестирование контрактов, часть 5: адаптация к изменениям |
27.05.2022 00:00 |
Автор: Баз Дейкстра (Bas Dijkstra) В предыдущей статье мы остановились на том, что у нас все в порядке с интеграционным тестированием: провайдер Address способен удовлетворить ожидания потребителей Customer и Order. Затем мы успешно справились с автоматизацией генерации контрактов и их публикации. Мы также автоматизировали их загрузку, проверку и публикацию результатов верификации на стороне провайдера. Однако, как все мы знаем, системы постоянно меняются, и в них часто добавляются новые требования и функции. В этой статье мы рассмотрим ситуацию, когда на стороне потребителя внедряются два различных требования, а затем разберемся, как это повлияет на результаты верификации со стороны провайдера и предположим, как справляться с проблемами интеграции в ходе тестирования контрактов. Добавление нового поля: поддержка абонентских ящиков Потребители нашего онлайн-магазина сэндвичей просят возможности указать абонентский ящик в качестве адреса выставления счета. По очевидным причинам ящики не будут использоваться в качестве адреса доставки! Иными словами, адреса, которые ожидает наш потребитель Customer, теперь имеют поле "Абонентский ящик". Это целое число, принимающее значение 0, если номер ящика неизвестен. Помните: нам не важно реальное значение – оно относится к бизнес-логике и должно покрываться тестами на стороне провайдера, а способность обрабатывать эти значения должна быть покрыта тестами на стороне потребителя. Тестирование контрактов в этом не задействовано – оно только убеждается, что поле действительно присутствует, и что значение в нем – целое число. Обновленные адресные данные теперь будут выглядеть как-то так: { а обновленные ожидания от тела ответа в Pact – вот так: DslPart body = LambdaDsl.newJsonBody((o) -> o Естественно, мы также обновляем юнит-тест, проверяющий, что наш потребитель Customer может верно обработать обновленный ответ. Мы добавляем утверждение в существующий тест: assertThat(address.getPoBox()).isEqualTo(POBOX); Вот и все с точки зрения потребителя Customer. Повторный запуск этих тестов покажет, что все тесты успешно пройдены, и когда мы ожидаем генерации обновленного контракта, то видим новое добавленное ожидание для нового поля poBox: "$.poBox": { Когда мы публикуем новый контракт для верификации провайдером Address, то видим, что он не может соответствовать новому ожиданию: [ERROR] Run 3: ContractTest Как можно видеть, результат работы Pact явно сообщает, что реальный ответ, возвращенный провайдером, не включает новое поле poBox – имеется конфликт интеграции. После обсуждения команда Address, отвечающая за разработку, тестирование и запуск провайдера Address, решила добавить поле poBox в ответ, направляемый потребителям Customer и Order. Тесты верификации контракта снова успешно выполняются: [INFO] Results: Все вновь прекрасно в мире контрактного тестирования. Как минимум, пока… Расширение рынка: поддержка канадских индексов В связи с повышенным спросом на сэндвичи в Канаде наш магазин решает поддерживать канадские адреса доставки. Сейчас из-за связанных с налогообложением причин только адреса США принимаются в качестве адресов выставления счета. Чтобы это реализовать, команда потребителя Order меняет свои ожидания от поля индекса – теперь это строка, а не целое число, потому что индексы в Канаде содержат и буквы, и цифры. Они решают не использовать регулярные выражения для проверки индекса, чтобы в будущем смочь поддерживать и другие индексы: DslPart body = LambdaDsl.newJsonBody((o) -> o Они соответственно обновляют свои юнит-тесты и запускают их, чтобы создать обновленный контракт. Публикуя этот контракт для провайдера Address и верификации, мы видим, что он не соответствует новому ожиданию: [ERROR] Run 3: ContractTest Если мы автоматически публикуем контракты и результаты верификации в Pactflow Pact Broker, как мы делали в предыдущей статье, мы увидим там ту же самую ошибку: Однако, в отличие от предыдущего изменения, провайдер Address не может просто обновить свою реализацию, чтобы выполнить ожидания и Customer, и Order. Один из потребителей ожидает, что индекс будет типа String, другой ожидает Integer, но Address может вернуть только что-то одно, не оба сразу! Это значит, что все три стороны должны обсудить наилучший способ решения этой проблемы. Это яркий пример проблем интеграции, стартующих на одной стороне, но затрагивающих другие команды, и выявленных при помощи контрактного тестирования. В шестой, заключительной, статье мы внедрим еще одно действующее лицо в процесс контрактного тестирования и разберемся, как Pact и экосистема PactFlow упрощают внедрение тестирования контрактов при помощи двусторонних контрактов. Код из статьи можно найти здесь. |