Pruebas de API contratadas
1) Por qué las pruebas contractuales
El contrato registra las expectativas del cliente y las promesas del proveedor: rutas/métodos, encabezados, esquemas de cuerpos, estados, semántica de errores y limitaciones. El objetivo es capturar cambios incompatibles antes de la integración y lanzar versiones de forma segura, sin E2E pesados.
2) Enfoques
Contratos de unidad de consumo (CDC): el cliente forma las expectativas (Pactos y contrapartes); el proveedor los verifica regularmente.
Especificación: contrato como fuente única de verdad (OpenAPI/Protobuf/GraphQL SDL); las pruebas validan la implementación contra la especificación.
Evento: esquemas de mensajes (Avro/JSON Schema/Protobuf) + reglas de compatibilidad en el corredor/registro.
3) HTTP/NAT: flujo de especificación
1. Contrato: OpenAPI 3. x (diagramas, ejemplos, códigos).
2. Lint y estatanálisis: estilo, campos obligatorios, códigos únicos.
3. Validación de implementación: generador de pruebas contra OpenAPI (schemathesis/enfoque Dredd) + negativos manuales.
4. Snapshots: capturar respuestas de ejemplo, semántica ETag, encabezados de idempotencia.
yaml paths:
/v1/payments:
post:
responses:
"201": { $ref: "#/components/responses/PaymentCreated" }
"409": { description: Duplicate by Idempotency-Key }
"422": { description: Schema/Business validation failed }
4) CDC (Enfoque de Pactos)
Ciclo de vida:1. Consumer escribe una prueba, forma un archivo de paquete (espera).
2. Publicación en un corredor (artefacto).
3. El proveedor en CI levanta el servicio (o el rack contractual), verifica el nat's.
4. El corredor calcula la matriz de compatibilidad can-i-deploy.
Ejemplo de prueba de consumo (pseudo-JS):js pact
.given("wallet exists")
.uponReceiving("get wallet")
.withRequest({ method:"GET", path:"/v1/wallets/w123", headers:{ "Authorization": term({generate:"Bearer x", matcher:/^Bearer\s.+/}) }})
.willRespondWith({
status: 200,
headers: { "Content-Type": "application/json" },
body: like({ id:"w123", currency: "EUR", balance: 0 })
});
5) gRPC/Protobuf contratos
El contrato es '.proto' con la versificación de paquetes/servicios.
Compatibilidad: no reutilizar etiquetas, sólo agregar nuevas con optional, no eliminar los campos utilizados; reservar números.
Pruebas: generación de la estabilidad del servidor/cliente, alquiler de casos generados por auto + negativos (campo desconocido, tamaño-límites).
6) Contratos de eventos (Kafka/NATS/...)
Схемы: Avro/JSON Schema/Protobuf в Schema Registry.
Política de compatibilidad: 'BACKWARD' (a menudo suficiente) o'FULL '.
Pruebas de producción: valida el mensaje contra el esquema; pruebas de consumer: acepta la versión antigua y la nueva.
Invariantes: claves de idempotencia, orden/repetibilidad, semántica de deduplicación.
json
{"type":"record","name":"PayoutCreated","fields":[
{"name":"payoutId","type":"string"},
{"name":"amount","type":"double"},
{"name":"currency","type":{"type":"string","logicalType":"iso-4217"}}
]}
7) Compatibilidad y versiones
Backward-compatible (mínimo recomendado): agregue campos opcionales, no rompa los existentes.
Forward-compatible: los consumidores ignoran campos desconocidos.
Full: ambos.
Versioning: 'path (/v1)', 'Accept: application/vnd. brand. v2+json`, `proto package v2`.
Política de depreciación: ventana de salida (por ejemplo, 90 días) que avisa a los encabezados/eventos.
8) Negativo y errores - también es un contrato
Estandarizar los códigos: 400/401/403/404/409/422/429/5xx, campos obligatorios 'code', 'message', 'trace _ id'.
Dimensiones/límites - parte del contrato (413/414/431).
Idempotencia: comportamiento de repetición (409 vs 201 same id).
Encabezados: 'Retry-After' a 429/503, 'Idempotency-Key', 'Content-Language', etc.
json
{ "code":"validation_error", "message":"amount must be ≥ 1", "trace_id":"..." }
9) Datos gestionados por el contrato
Ejemplos/Respuestas de orden (ejemplos) - en vivo, validado en CI.
Las fixturas para CDC son mínimas, deterministas.
Generación de datos - property-based para números/fechas; pero no romper la estabilidad de los snapshots.
10) Pipeline en CI/CD (referencia)
1. Lint/validate: OpenAPI/Proto/Avro (`validate`, style-линер).
2. Publish: contrato como artefacto (corredor/registro).
3. Verify: el proveedor ejecuta los paquetes de CDC/pruebas de especificación.
4. can-i-deploy gate: sin matriz verde, la liberación está prohibida.
5. Diff: comprobar que los cambios son compatibles (diff semántico).
6. Informe: AMBnit/HTML, lista de infracciones/definiciones.
yaml jobs:
lint:...
publish-contract: needs: [lint]
verify-provider: needs: [publish-contract]
can-i-deploy:
if: always()
steps: [run: pact-broker can-i-deploy...]
11) Herramientas (por clase de tareas)
Lint/validadores: openapi-linters, protobuf-lint, avro-tools.
CDC: Aprox-family/bróker, Spring Cloud Contract, Hoverfly (grabaciones/réplicas HTTP).
Ranners de especificación: schemathesis/enfoque similar a Dredd, Postman test + JSON Schema.
Diff: semantic-diff OpenAPI/Proto/Avro (identifica cambios de breaking).
Contenedores: Testcontainers para levantar proveedores/contratos de rack.
12) Antipatternas
El «Spetz-dock» por separado del código → la resincronización. Mantenga el contrato cerca del servicio.
Los lavados de un servicio de terceros en lugar de un contrato → fragilidad en los apdates.
Respuestas/generación aleatoria sin referencia al diagrama de Flake →.
Cambio de tipos/obligatoriedad de campos sin versión.
Extensiones silenciosas sin notificación/deprecación.
Ausencia de contratos negativos y códigos de error.
13) Especificidad de iGaming/finanzas
Formaliza los campos monetarios: 'amount' - decimal con escala, moneda - ISO-4217, invariantes de sumas.
Contratos de pago/webhooks: HMAC/mTLS, anti-replay (ventana 'X-Timestamp'), idempotencia, 'Retry-After'.
Regionalidad/tenantes: títulos obligatorios 'X-Tenant/X-Region', localización de mensajes.
Eventos: registros inmutables (audit), claves de deduplicación, garantías de entrega (at least once + handlers idempotentes).
14) Ejemplos de «esqueletos» de pruebas
14. 1 Estilo Schemathesis (pseudo)
bash schemathesis run openapi. yaml --checks all --hypothesis-deadline=200
14. 2 Postman como ranner de especificación
js pm. test ("Scheme/v1/wallets/{ id} is valid," () => {
const schema = pm. collectionVariables. get("wallet_get_schema");
pm. expect(ajv. validate(JSON. parse(schema), pm. response. json())). to. be. true;
});
14. 3 Provider-verificación CDC (pseudo)
bash pact-broker can-i-deploy --pacticipant wallets --version $SHA --to-environment staging
15) Lista de comprobación prod
- Contratos en el repositorio, CI valida y publica artefactos.
- CDC está habilitado para integraciones críticas; funciona broker/matrix «can-i-deploy».
- La política de compatibilidad (HTTP/gRPC/Events) está documentada; semantic-diff automático.
- Contratos negativos: errores, límites de tamaño, idempotencia, 'Retry-After'.
- Los datos de prueba son deterministas; los snapshots de ejemplos son compatibles.
- Versioning y deprecation: plazos, notificaciones, encabezados.
- Para eventos - Registro de Schema y modo de compatibilidad; el productor/consumidor prueban ambas versiones.
- Artefactos: AMBnit/HTML, informes diff/verify, matriz de compatibilidad.
- Incidente-procedimiento: rollback rápido del contrato/bandera de ficha, aviso a los integradores.
16) TL; DR
Capture las expectativas en los contratos y ejecute automáticamente: CDC para las expectativas del cliente, pruebas de especificación para cumplir con la implementación, registro de esquemas para eventos. Mantenga una estricta política de compatibilidad y contratos negativos (errores, límites, idempotencia). No se puede lanzar sin una matriz de can-i-deploy verde y un diff semántico sin cambios de breaking.