Когда микросервисов становится больше пяти, ручное согласование API превращается в ад. Одна команда поменяла ответ, другая не в курсе - и здравствуй, 502 на проде. Pact решает это без поднятия всей системы, но требует правильной настройки провайдера.
Верификация провайдера
Берём
pact-python, пишем простой Flask-ручку:@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
return jsonify({'id': user_id, 'name': 'Alice'}), 200Verifier берёт Pact-файл от consumer и проверяет, что провайдер отдаёт то, что ожидают:
verifier = Verifier(provider='UserService',
provider_base_url='http://localhost:5000')
success, _ = verifier.verify_pacts(
'pacts/user_service-consumer.json',
provider_states_setup_url='http://localhost:5000/_pact_states')
Provider states - ключевая сложность
Consumer говорит: «перед тестом создай юзера», «перед тестом удали». Провайдер должен уметь отвечать на разные состояния. Заводим endpoint для подготовки данных:
@app.route('/_pact_states', methods=['POST'])
def set_state():
state = request.json.get('state')
if state == 'user exists':
create_test_user(id=1, name='Alice')
elif state == 'user not found':
delete_test_user(1)
return '', 204Verifier дёргает его автоматически перед каждым тестом. Без этого не пройдёт кейс «нет пользователя» - ответ будет 404, а consumer ждёт 200.
CI-интеграция через Pact Broker
Consumer публикует контракт после своих тестов:
pact-broker publish pact_file.json \
--consumer-app-version $CI_COMMIT_SHA \
--branch $CI_COMMIT_BRANCH \
--broker-base-url https://pact-broker.example.com
Провайдер в своём CI скачивает последнюю версию контракта и проверяет:
pact-broker can-i-deploy \
--pacticipant UserService \
--version $CI_COMMIT_SHA \
--broker-base-url https://pact-broker.example.com
Если несовместимо - CI падает. Деплой блокируется. После успешной верификации провайдер отмечает контракт как проверенный:
pact-broker record-verification \
--provider UserService \
--provider-app-version $CI_COMMIT_SHA \
--broker-base-url https://pact-broker.example.com
Когда это избыточно?
Если у вас монолит или 2-3 сервиса с ручными тестами - проще интеграционные. Pact окупается, когда число сервисов >5 и API стабилизировался. Если контракты меняются каждый спринт - будет больно пересогласовывать. Но для зрелых систем это стандарт.
Вывод: Pact-верификация с provider states и автоматической блокировкой деплоя через can-i-deploy делает контрактное тестирование надежным инструментом без ручного согласования, но требует дисциплины в CI и четкого разделения состояний.