¿Por Qué Contract Testing?
En microservicios, los servicios se desarrollan y despliegan independientemente. Sin contract testing, dependes de integration tests (lentos y frágiles), documentación (puede estar desactualizada) o esperanza.
Contract testing verifica que los servicios pueden comunicarse correctamente sin necesitar que todos estén ejecutándose al mismo tiempo.
Cómo Funciona Pact
Pact usa un enfoque consumer-driven: el consumidor define lo que espera, Pact genera un contrato, el proveedor lo verifica.
Escribiendo Tests de Consumidor
const { PactV3, MatchersV3 } = require('@pact-foundation/pact');
const { like, string, integer } = MatchersV3;
const provider = new PactV3({
consumer: 'OrderService',
provider: 'UserService',
});
describe('UserService contrato', () => {
test('obtener usuario por ID', async () => {
await provider
.given('usuario con ID 123 existe')
.uponReceiving('solicitud para usuario 123')
.withRequest({ method: 'GET', path: '/users/123' })
.willRespondWith({
status: 200,
body: {
id: integer(123),
name: string('Alice'),
email: string('alice@example.com'),
},
});
await provider.executeTest(async (mockServer) => {
const userClient = new UserClient(mockServer.url);
const user = await userClient.getUser(123);
expect(user.id).toBe(123);
});
});
});
Escribiendo Tests de Proveedor
const { Verifier } = require('@pact-foundation/pact');
describe('UserService verificación de proveedor', () => {
test('verifica todos los contratos', async () => {
const verifier = new Verifier({
providerBaseUrl: 'http://localhost:3001',
pactBrokerUrl: 'https://your-broker.pact.io',
provider: 'UserService',
stateHandlers: {
'usuario con ID 123 existe': async () => {
await db.users.create({ id: 123, name: 'Alice', email: 'alice@example.com' });
},
},
});
await verifier.verifyProvider();
});
});
Matchers de Pact
Los matchers hacen los contratos flexibles: like() para tipo, string() para strings, integer() para enteros, eachLike() para arrays, regex() para patrones.
Pact Broker
Repositorio central para contratos. El comando can-i-deploy responde: “¿es seguro desplegar esta versión?”
Ejercicio: Implementación de Contract Testing
Tarea 1: Tests de Contrato del Consumidor
Escribe tests para un OrderService que consume un ProductService API con 4 interacciones.
Tarea 2: Verificación del Proveedor
Escribe tests de proveedor con state handlers para cada estado “given”.
Tarea 3: Integración con Pact Broker
Configura Pact Broker local, publica contratos, configura verificación del proveedor, usa can-i-deploy.
Tarea 4: Detección de Breaking Changes
Haz un breaking change, ejecuta verificación, documenta la falla, corrige.
Tarea 5: Integración en Pipeline CI
Diseña pipeline: Consumer CI publica contratos, Provider CI los verifica.
Entregables
- Código de tests de consumidor con al menos 4 interacciones.
- Código de verificación de proveedor con state handlers.
- Configuración de Pact Broker.
- Documento de diseño de pipeline CI.
- Demostración de detección de breaking changes.