GH GambleHub

Pruebas contractuales

1) Dónde aplicar los contratos

^/JSON HTTP: recursos, paginación, filtros, idempotencia, códigos de error.
gRPC/Protobuf: tipos de mensajes, estados, semántica 'deadline', backward-compat v.proto.
GraphQL: esquemas, non-null, directivas, pérmicas en los campos.
Mensajes/streams (Kafka/Pulsar/SQS): diagramas de eventos (Avro/JSON/Protobuf), llaves de lote, orden, llaves idempotentes.
SDK/bibliotecas internas: funciones públicas/exclusiones/contratos de rendimiento.


2) Modelo CDC: roles y artefactos

El consumidor publica un contrato de expectativas (consultas/respuestas aproximadas, tipos de matters, invariantes).
El proveedor ejecuta la verificación de los contratos contra su servicio/adaptador/handler's.
El intermediario de contratos (Aprox Broker/Backstage/artefacto repo) almacena versiones, etiquetas ('prod',' staging ',' canary ') y la matriz de compatibilidad' consumer @ v → provider @ v '.
Política de lanzamiento: se prohíbe el envío de un proveedor si se infringe cualquier contrato «prod-relevante».


3) Qué fijar en un contrato (ejemplo HTTP)

Mínimo:
  • Método/ruta/parámetros/encabezados (auth incluido, clave idempotente).
  • Cuerpo y tipos de matches (tipo/formato/regexp/rangos).
  • Códigos y estructura de errores; estable 'error _ code'.
  • Invariantes semánticos: clasificación, singularidad, monotonía 'created _ at'.
  • Espera no funcional (opcional): p95, límites de tamaño, rate-limit encabezados.
Fragmento del contrato (simplificado):
json
{
"interaction": "GET /v1/users/{id}",
"request": { "method": "GET", "path": "/v1/users/123", "headers": {"Accept":"application/json"} },
"matchers": {
"response.body.id": "type:number",
"response.body.email": "regex:^.+@.+\\..+$",
"response.body.created_at": "format:rfc3339"
},
"response": {
"status": 200,
"headers": {"Content-Type":"application/json"},
"body": {"id": 123, "email": "alice@example.com", "created_at": "2025-10-31T12:00:00Z"}
},
"error_cases": [
{
"name":"not_found",
"request":{"path":"/v1/users/9999"},
"response":{"status":404, "body":{"error_code":"USER_NOT_FOUND"}}
}
]
}

4) Contratos para eventos (event-driven)

Esquema de eventos: 'type', 'version', 'id', 'occurred _ at _ utc', 'producer', 'subject', 'payload'.
Invariantes: inmutabilidad 'id' e idempotencia por '(tipo, id)', orden dentro de la clave de lote, monotonía 'sequence'.
Registro de Schema: almacena la evolución y las reglas de compatibilidad (backward/forward/full).
Pruebas de contrato de consumer: replica eventos de «oro» y fases de negativos (campos desconocidos, nullable).

Ejemplo de diagrama Avro (fragmento):
json
{
"type":"record","name":"UserRegistered","namespace":"events.v1",
"fields":[
{"name":"id","type":"string"},
{"name":"occurred_at_utc","type":{"type":"long","logicalType":"timestamp-millis"}},
{"name":"email","type":"string"},
{"name":"marketing_opt_in","type":["null","boolean"],"default":null}
]
}

5) Evolución y compatibilidad

Versiones de contratos: semántica 'MAJOR. MINOR. PATCH '(MAJOR - rompiendo).

Reglas para NAT:
  • No rompa: no elimine campos, no cambie el tipo/valor de 'error _ code'.
  • Agregue campos opcionales con default; nuevos endpoints en lugar de «magia».
  • Deprecación: anuncio, soporte paralelo, eliminación por métricas.
  • GraphQL: los campos sólo añadir, no-null introducir a través de las fases; directivas de deprecación.
  • gRPC/Proto: no volver a usar los números de campo; sólo añadir nuevos con optional.
  • Eventos: esquema 'vN'; los consumistas están obligados a ignorar los campos desconocidos (leninidad).

6) Comprobaciones negativas e invariantes

Negative: tipos incorrectos, valores prohibidos, parámetros de conflicto, exceso de límites.
Invariantes: ordenamiento de respuestas, unicidad 'id', corrección 'next _ cursor', estabilidad de respuesta idempotente cuando se repite.
Los contratos de los aspectos temporales: 'created _ at' RFC3339/UTC, la proyección correcta del día local no es parte del contrato de transporte - se lleva a las invariantes comerciales.


7) Generación y desarrollo local

A partir de los contratos se generan bandadas de proveedores para el desarrollo del consumidor.
Para los eventos, los generadores de mensajes «válidos/fronterizos» en el esquema.
Las bandadas se marcan con la versión del contrato y la fecha de montaje; prohibida la publicación en el prod.


8) Incrustación en CI/CD (pipeline de referencia)

1. Consumer CI:

Lint/ensamblaje → generación de contratos → units/pruebas de contrato → publicación en contract-broker (tag: 'consumer @ 1. 7. 0`).

2. Provider CI:

Elevar el servicio localmente/en contenedor → fetch de contratos relevantes ('prod'/' staging') → verificación → publicación del estado en broker.

3. Release Gate:

El deploy del proveedor se bloquea si hay contratos pendientes.

4. Nightly Matrix:

Matriz de compatibilidad 'consumer versions × provider versions'; informes y alarmas.


9) Ejemplos de prácticas de dominio

9. 1 NAT: paginación por cursores (invariante contractual)

La respuesta contiene 'items []', 'next _ cursor' (nullable), 'limit', 'total' (opcional).
Invariantes: 'len (items) ≤ limit', una llamada repetida con el mismo 'cursor' → un conjunto idempotente.
Error si se especifican 'cursor' y 'page' al mismo tiempo.

9. 2 Idempotencia POST

El contrato requiere la rúbrica 'Idempotency-Key'.
Invariante: una consulta repetida con la misma clave devuelve el mismo 'id '/estado.

9. 3 Eventos: Garantías de orden

Clave de lote en el contrato: 'partition _ key = user_id'.
Invariante: 'sequence' aumenta monótonamente dentro de la clave; el consumidor está obligado a procesar las repeticiones.


10) Seguridad y privacidad en los contratos

No incluir PDn/secretos en los ejemplos es sólo sintético.
Fijar títulos de seguridad obligatorios: 'Authorization', 'X-Signature', 'Replay-Prevention'.
Para webhooks es un contrato de firma y respuesta '2xx '/retrayes.
En los logs de pruebas de contrato, enmascarar campos sensibles.


11) Herramientas

Aprox/Pactflow/Aprox Broker - Contratos HTTP/Message, matriz de compatibilidad.
OpenAPI/AsyncAPI - Especificaciones + generadores de prueba (Dredd, Schemathesis).
Karate/NAT Assured - Comprobaciones de script de los contratos NAT.
Protobuf/gRPC - 'buf', 'protolint', pruebas de compatibilidad; Registro de Schema para Avro/JSON/Proto en subprocesos.
Pruebas de conformación para GraphQL (graphql-compat), pruebas de esquema snapshot.


12) Pseudo código de verificación del proveedor (simplificado)

python def verify_contract(provider, contract):
for case in contract["cases"]:
req = build_request(case["request"])
res = provider.handle(req) # локально/контейнер assert match_status(res.status, case["response"]["status"])
assert match_headers(res.headers, case["response"].get("headers", {}))
assert match_body(res.body, case["matchers"], allow_extra_fields=True)
for neg in contract.get("error_cases", []):
res = provider.handle(build_request(neg["request"]))
assert res.status == neg["response"]["status"]
assert res.json.get("error_code") == neg["response"]["body"]["error_code"]

13) Anti-patrones

«Las capturas de pantalla de Postman son un contrato»: no hay versiones/matches tipo/validación automática.
Oversnaping: el contrato registra los valores exactos en lugar de los tipos/patrones → las caídas falsas.
Un contrato común para diferentes regiones/canales: ignora la variabilidad (banderas, reglas geo).
Contratos sin bróker/matriz: no se puede entender qué versiones son compatibles.
Apuesta por e2e en lugar de contratos: lento, caro, inestable.
Ausencia de casos negativos/invariantes: sólo se prueba la «pista verde».


14) Observabilidad y explotación

Exportar el estado a broker + dashboard «contratos de salud».
Alertas: nuevas caídas del proveedor contra los contratos 'prod', crecimiento del' campo desconocido 'en los eventos.
Rastreo: 'aprox _ id', 'version', 'decision _ id' en los logs de verificación.


15) Proceso de deprecación

1. Agregar campo/endpoint (no rompedor).
2. Marcar el antiguo como 'deprecated' en la especificación, declarar los plazos.
3. Rastrear a los consumidores por logotipos/bróker; gaidas migratorias.
4. Incluir el deny «sombreado» en el stage (dry-run), luego enforce.
5. Eliminar después de la cuota de uso cero y la confirmación de compatibilidad.


16) Check-list del arquitecto

1. ¿Identificados los consumidores y sus propietarios? ¿Los contratos son versionables?
2. ¿Hay un broker y una matriz de compatibilidad con etiquetas de entorno?
3. ¿El contrato incluye negativos e invariantes (idiempotencia, cursores, clasificación)?
4. ¿Ha configurado Schema Registry y el modo de compatibilidad para los eventos?
5. ¿Pipeline bloquea la liberación del proveedor cuando se violan los contratos prod?
6. ¿Se describe el proceso de deprecación y la política de evolución?
7. Se generan bandadas a partir de contratos, ¿hay generadores de eventos locales?
8. ¿Está documentado el enmascaramiento del PD y los títulos de seguridad obligatorios?
9. Las métricas/alertas contractuales están conectadas, ¿hay informes de deriva?
10. ¿Los contratos son verificados en CI por ambas partes (consumer y provider)?


Conclusión

Las pruebas contractuales transfieren la «verdad» sobre las interacciones a artefactos versionables y hacen previsibles las integraciones. Los CDC, el corredor de contratos y la disciplina de la evolución de los circuitos sustituyen las «sorpresas rompedoras» por un proceso gestionado: verificaciones rápidas, invariantes claros y compatibilidad transparente de las versiones. Esto reduce el costo de e2e, acelera las versiones y mejora la calidad de toda la plataforma.

Contact

Póngase en contacto

Escríbanos ante cualquier duda o necesidad de soporte.¡Siempre estamos listos para ayudarle!

Iniciar integración

El Email es obligatorio. Telegram o WhatsApp — opcionales.

Su nombre opcional
Email opcional
Asunto opcional
Mensaje opcional
Telegram opcional
@
Si indica Telegram, también le responderemos allí además del Email.
WhatsApp opcional
Formato: +código de país y número (por ejemplo, +34XXXXXXXXX).

Al hacer clic en el botón, usted acepta el tratamiento de sus datos.