O Que São Testes de Contrato?
Testes de contrato verificam que a interface entre serviços (API) está funcionando conforme acordado. Cada serviço define o que espera e o que fornece.
Problema
Microservice A (Consumer)
↓
API REST
↓
Microservice B (Provider)
Se B muda API sem avisar A → BUG!
Solução: Contract Testing
┌─────────────┐ ┌─────────────┐
│ Consumer │ Contract │ Provider │
│ Test │ ←──────────────→ │ Test │
└─────────────┘ └─────────────┘
↓ ↓
[Pact Broker] ←──────────────────────────
Pact – Framework de Contract Testing
Setup
# Ruby
gem install pact
# Python
pip install pact-python
# Java
au.com.dius.pact
jvm-consumer
4.6.4
Consumer Test (Python)
# test_consumer.py
import pact
# Provider URL
PACT_MOCK_PROVIDER_URL = "http://localhost:1234"
# Define consumer and provider
consumer = pact.Consumer('OrderService')
provider = pact.Provider('ProductService')
# Create pact
order_service_pact = consumer.has_pact_with(
provider,
pact_dir='./pacts',
log_dir='./logs'
)
# Test
order_service_pact.given(
'product with id 1 exists'
).upon_receiving(
'a request for product details'
).with_request(
method='GET',
path='/products/1'
).will_respond_with(
status=200,
headers={'Content-Type': 'application/json'},
body={
'id': 1,
'name': pact.Match.something_like('Test Product'),
'price': pact.Match.decimal(99.99),
'in_stock': pact.Match.boolean(True)
}
)
# Verify
with order_service_pact:
result = requests.get(f'{PACT_MOCK_PROVIDER_URL}/products/1')
assert result.status_code == 200
assert result.json()['name'] == 'Test Product'
Provider Test (Python)
# test_provider.py
import pact
from pact import Verifier
# Verify against provider
verifier = Verifier(
provider='ProductService',
provider_base_url='http://localhost:8000'
)
# Set up Pact file to verify
verifier.provider_states(
'http://localhost:8000',
set_up=lambda state: create_test_product() if state == 'product with id 1 exists' else None,
tear_down=lambda state: delete_test_product() if state == 'product with id 1 exists' else None
)
# Verify contracts
result = verifier.verify_pacts(
'./pacts/order_service-product_service.json',
verbose=True
)
assert result == 0, f"Pact verification failed: {result}"
Pact Broker
# Publish contract
pact-broker publish ./pacts
--consumer-app-version=1.0.0
--broker-base-url=https://pact-broker.example.com
--broker-token=YOUR_TOKEN
# Can I Deploy?
pact-broker can-i-deploy
--pacticipant=OrderService
--version=1.0.0
--to-environment=production
Conclusão
Contract testing previne breaking changes. As chaves são:
- Consumer-driven – Cada cliente define necessidades
- Pact broker – Centraliza contratos
- Verificação contínua – CI valida mudanças
- Can I Deploy – Bloca deploys incompatíveis
