system onlinepath: /guias/testing/contract-testing-de-apis-con-pact/mode: knowledge_baselocal:
Testing y QA · Nivel intermedio

Contract Testing de APIs y microservicios con Pact

Probar que dos servicios se entienden sin levantarlos juntos. Cómo funciona el flujo dirigido por el consumidor, qué hace el broker, y por qué la pregunta «¿puedo desplegar?» pasa a tener una respuesta con datos.

14 min de lectura▣ Actualizada el ◇ Por Underc0de
Respuesta rápida

El contract testing es, según la documentación de Pact, una técnica para probar un punto de integración revisando cada aplicación por separado, para asegurar que los mensajes que envía o recibe cumplen un entendimiento compartido documentado en un contrato. Funciona en dos fases: en el consumidor, los tests corren contra un proveedor simulado y generan un archivo de pacto que describe cada interacción; en el proveedor, cada petición del pacto se reproduce contra el servicio real y se comprueba que la respuesta contenga al menos los datos que el consumidor declaró necesitar. El broker guarda contratos y resultados, y responde con datos la pregunta «¿puedo desplegar esta versión?».

Ver índice de contenidos
  1. 01El problema que resuelve
  2. 02Qué es, con precisión
  3. 03Consumidor y proveedor
  4. 04Por qué lo dirige el consumidor
  5. 05Fase 1: en el consumidor
  6. 06Fase 2: en el proveedor
  7. 07La respuesta mínima esperada
  8. 08El broker y «can-i-deploy»
  9. 09Contract testing y OpenAPI
  10. 10Qué no cubre
  11. 11Errores frecuentes
  12. 12Preguntas frecuentes
  13. 13Fuentes

El problema que resuelve

Con dos servicios, probar que se entienden es fácil: los levantás juntos y listo. Con quince servicios que se llaman entre sí, ese enfoque se desarma, y siempre por las mismas tres razones:

  • Hay que levantar todo junto. Cada prueba necesita el resto del sistema corriendo, con sus bases de datos y sus dependencias.
  • Es lenta y frágil. Cualquier servicio caído, cualquier dato inconsistente, cualquier lentitud de red hace fallar pruebas que no tenían nada que ver.
  • Cuando falla, no dice quién rompió qué. Este es el peor de los tres: una prueba roja en un entorno compartido inicia una investigación entre equipos en lugar de señalar al responsable.

Y hay un problema anterior, más silencioso: el proveedor de una API no sabe quién usa qué. Cuando alguien quiere renombrar un campo, la pregunta «¿esto rompe a alguien?» no tiene respuesta, así que se elige entre no cambiar nada nunca o cambiar y esperar.

Qué es, con precisión

i
La definición, de la documentación de Pact

«El contract testing es una técnica para probar un punto de integración comprobando cada aplicación por separado para asegurar que los mensajes que envía o recibe se ajustan a un entendimiento compartido que está documentado en un contrato

La expresión que hace todo el trabajo es «por separado». El contrato existe justamente para que cada lado pueda verificarse solo, en su propio pipeline, sin el otro corriendo. De ahí salen las tres ventajas que son el reverso exacto de los tres problemas anteriores: es rápido, no es frágil, y cuando falla se sabe qué lado incumplió.

Pact es la herramienta de código abierto más difundida para hacerlo. Es code-first: el contrato no se escribe en un documento aparte, se genera ejecutando los tests del consumidor.

Consumidor y proveedor

Dos términos y conviene fijarlos bien, porque todo lo demás depende de ellos:

  • Consumidor: la aplicación que pide los datos. Un frontend, un servicio que llama a otro, un trabajo que lee de una cola.
  • Proveedor: la aplicación que entrega los datos. Una API, un servicio, quien publica en la cola.

Pact usa estos términos y no «cliente» y «servidor» de forma deliberada: el vocabulario se aplica igual a la comunicación por mensajes, donde las etiquetas cliente-servidor no encajan. Un mismo servicio suele ser consumidor de unos y proveedor de otros al mismo tiempo, y va a tener contratos en los dos roles.

Por qué lo dirige el consumidor

Pact usa el enfoque dirigido por el consumidor: el contrato «se genera durante la ejecución de los tests automatizados del consumidor». No lo escribe quien publica la API, lo produce quien la usa.

La lógica es sólida: quien consume es el único que sabe qué necesita de verdad. Un proveedor que documenta su API describe todo lo que ofrece; un consumidor que genera un pacto documenta exactamente los campos que usa, ni uno más.

La documentación describe el enfoque como «contrato por ejemplo»: cada caso de prueba describe un par concreto de petición y respuesta que después se verifica, en lugar de una especificación abstracta.

El beneficio que se aprecia a los seis meses

El proveedor deja de trabajar a ciegas. Cuando alguien pregunta «¿puedo quitar este campo?», la respuesta ya no es una opinión: está en los contratos publicados. Si ningún consumidor lo declaró, se quita sin drama; si tres lo usan, se sabe con quién hay que hablar. Esa información es el producto principal del contract testing, más incluso que las pruebas en sí.

Fase 1: en el consumidor

El flujo del contract testing con Pact. Arriba, la comparación entre pruebas de integración de punta a punta, que exigen levantar todos los servicios y no indican quién rompió qué, y contract testing, donde cada aplicación se prueba por separado. En la fase del consumidor: se registran la petición y respuesta esperadas, el consumidor hace una petición real contra un proveedor simulado, el simulado compara y responde, y el consumidor confirma que entendió la respuesta; al final se genera el archivo de pacto. En medio, el broker guarda contratos y resultados y responde si se puede desplegar. En la fase del proveedor, cada petición del pacto se envía al proveedor real y la respuesta se compara con la mínima esperada.
El contrato lo escribe quien consume, con lo que realmente usa. De ahí «dirigido por el consumidor».

La documentación de Pact describe cuatro pasos, y el detalle importa porque explica por qué el resultado es confiable:

  1. Se registran la petición y la respuesta esperadasUsando el lenguaje de Pact, se declara qué se va a pedir y qué se espera recibir. Ese registro se hace contra un servicio simulado.
  2. El código del consumidor hace una petición realY acá está la clave: real, contra el proveedor simulado que crea el propio marco. No se simula la llamada: se ejecuta el código de tu cliente HTTP con toda su configuración.
  3. El simulado compara y respondeCompara la petición que llegó con la esperada, y si coincide emite la respuesta declarada.
  4. El consumidor confirma que la entendióEl test verifica que tu código procesó esa respuesta correctamente.

El marco exige que «los tests de Pact solo son exitosos si cada paso se completa sin error». Esa doble comprobación —tu código pide bien y entiende bien— es lo que evita el problema clásico de los mocks escritos a mano: un simulacro que devuelve lo que tu código espera, aunque el servicio real devuelva otra cosa.

Al terminar, «el marco de Pact genera un archivo de pacto que describe cada interacción». Ese archivo JSON es el contrato.

Fase 2: en el proveedor

La segunda fase invierte el flujo. Cada interacción del pacto se reproduce contra el proveedor real: «en la verificación del proveedor, cada petición se envía al proveedor, y la respuesta que genera se compara con la respuesta mínima esperada descrita en el test del consumidor».

Tres cosas que conviene notar de esta fase:

  • El proveedor corre de verdad. Con su código, sus validaciones y su serialización. Lo que se simula, si hace falta, son sus dependencias.
  • Corre en el pipeline del proveedor. No hace falta el consumidor: solo el archivo de pacto.
  • Necesita estados previos. Si el pacto dice «pedido 42 existe y está pagado», el proveedor tiene que poder llegar a ese estado antes de responder. Pact llama a eso provider states, y es la parte que más trabajo de configuración lleva.

La respuesta mínima esperada

Este es el concepto más elegante del diseño y el que hay que entender para no usarlo mal. La verificación pasa cuando «cada petición genera una respuesta que contiene al menos los datos descritos en la respuesta mínima esperada».

Cambios del proveedor que rompen o no rompen el contrato
Cambio en el proveedor¿Rompe el contrato?Por qué
Agregar un campo nuevo a la respuestaNoEl consumidor nunca dijo que la respuesta debiera tener solo esos campos
Quitar un campo que un consumidor declaró usarFalta un dato que estaba en la respuesta mínima
Renombrar ese campoEquivale a quitarlo
Cambiar su tipo, de número a textoEl consumidor declaró el tipo que necesita
Cambiar el código de estadoEs parte de la interacción declarada
Agregar un campo obligatorio a la peticiónLa petición del consumidor ya no sería válida

Fijate que ese conjunto es exactamente el de los cambios que en producción romperían a alguien, y ninguno más. Por eso el contract testing no se convierte en un freno: la evolución compatible pasa sin ruido y solo se detiene lo que de verdad rompe.

El broker y «can-i-deploy»

Con los contratos generándose en un pipeline y verificándose en otro, aparece un problema de información: «los números de versión de todas las aplicaciones que se probaron juntas, y si las pruebas pasaron o fallaron» quedan repartidos entre muchas ejecuciones de CI.

El Pact Broker es «una aplicación para compartir contratos dirigidos por el consumidor y resultados de verificación». Reúne esos datos y permite determinar qué versiones de tus aplicaciones se pueden desplegar juntas de forma segura.

Su consecuencia más útil es un comando:

bash
# Antes de desplegar, preguntar si esta versión es compatible
pact-broker can-i-deploy \
  --pacticipant NOMBRE_DEL_PROVEEDOR \
  --version VERSION_DEL_PROVEEDOR

Lo usan los dos lados: el proveedor antes de desplegar, para confirmar compatibilidad con los consumidores que ya están en el ambiente; y el consumidor antes de liberar su cambio. Es la diferencia entre desplegar con información y desplegar con esperanza.

El broker además versiona los contratos automáticamente y maneja etiquetas y ramas, que permiten marcar qué versión está en cada ambiente y comprobar compatibilidad hacia atrás entre varias versiones de consumidores y proveedores.

Contract testing y OpenAPI

Es la pregunta que aparece siempre, y no son alternativas: resuelven cosas distintas.

Diferencias entre una especificación OpenAPI y un pacto
 Especificación (OpenAPI)Pacto
Qué describeTodo lo que la API ofreceSolo lo que un consumidor concreto usa
Quién lo escribeEl proveedorSe genera con los tests del consumidor
Cómo se mantieneA mano; se desactualizaSe regenera al correr los tests
Responde «¿puedo cambiar esto?»No: no sabe quién usa quéSí, con nombres de consumidores
Sirve como documentación públicaSí, es su fuerteNo: es una herramienta de verificación

Lo habitual y sensato es tener las dos: la especificación como documentación y contrato de diseño, y los pactos como red de seguridad de lo que efectivamente se consume.

Qué no cubre

Prometer más de esto es la forma más común de que la iniciativa se abandone a los tres meses:

  • No verifica la lógica de negocio. Comprueba que la respuesta tenga un campo total numérico, no que el total esté bien calculado. Eso son pruebas unitarias y funcionales.
  • No verifica que los datos sean correctos. Solo su forma y sus tipos.
  • No reemplaza todas las pruebas de punta a punta. Reemplaza a las que solo comprobaban que dos servicios se entendieran; conviene conservar unas pocas para los flujos críticos completos.
  • No cubre rendimiento ni carga. Para eso, pruebas de rendimiento con k6 y Grafana.
  • No sirve para APIs de terceros que no controlás. Nadie va a correr tu verificación en el pipeline de un proveedor externo. Ahí lo que sirve son pruebas de contrato contra su especificación y monitoreo.
  • Tiene costo de adopción. Los provider states y la integración con CI llevan trabajo real. En un sistema con dos servicios, probablemente no valga la pena.

Errores frecuentes

  • Escribir el pacto desde el proveedor. Pierde todo el sentido: vuelve a describir lo que se ofrece en lugar de lo que se usa.
  • Declarar en el pacto campos que no se usan. Cada campo declarado es una restricción que el proveedor no va a poder cambiar. Declarar solo lo que consumís.
  • Usar valores exactos donde alcanza el tipo. Si tu código solo necesita que id sea un número, declarar que vale exactamente 42 vuelve el contrato frágil sin ganar nada.
  • Verificar contra un proveedor simulado. La fase 2 pierde todo su valor si no corre contra el servicio real.
  • No publicar los pactos en un broker. Sin broker no hay can-i-deploy, y se pierde el beneficio principal.
  • Prometer que reemplaza las pruebas de integración. Genera una expectativa que no se cumple y desprestigia la práctica.
  • Adoptarlo en un sistema con dos servicios. El costo de configuración no se recupera; conviene cuando hay varios equipos desplegando por separado.

Preguntas frecuentes

¿Qué es el contract testing en una frase?

Según la documentación de Pact, es una técnica para probar un punto de integración revisando cada aplicación por separado, para asegurar que los mensajes que envía o recibe cumplen con un entendimiento compartido documentado en un contrato. La palabra clave es «por separado»: en lugar de levantar los dos servicios juntos, cada uno se verifica contra el contrato en su propio pipeline. Eso es lo que lo hace rápido y lo que permite saber cuál de los dos lados incumplió cuando algo falla.

¿Cuál es la diferencia con usar OpenAPI o Swagger?

Una especificación describe todo lo que la API ofrece; un pacto describe solo lo que un consumidor concreto realmente usa. Esa diferencia tiene una consecuencia práctica enorme: con una especificación no sabés si podés cambiar un campo, porque no sabés quién lo usa. Con contract testing sí, porque cada consumidor documentó lo que consume. Además, Pact es contrato por ejemplo y se genera ejecutando los tests reales del consumidor, así que no puede quedar desactualizado respecto del código como sí le pasa a un documento escrito a mano.

¿Por qué se dice que el contrato lo dirige el consumidor?

Porque el contrato no lo escribe quien publica la API sino quien la usa, y se genera durante la ejecución de los tests automatizados del consumidor. La lógica es que quien consume es el único que sabe qué campos necesita de verdad. El resultado es un contrato mínimo y honesto: contiene exactamente lo que se usa, ni más ni menos. Eso le da al proveedor la información que más le falta cuando quiere cambiar algo: quién depende de qué.

¿Rompe el contrato si el proveedor agrega un campo nuevo?

No, y ese es uno de los aciertos del diseño. La verificación pasa si cada petición genera una respuesta que contiene al menos los datos descritos en la respuesta mínima esperada por el consumidor. Agregar campos nuevos no rompe nada, porque el consumidor no declaró que la respuesta debía tener solo esos campos. Lo que sí rompe el contrato es quitar o renombrar un campo que algún consumidor declaró usar, cambiar su tipo, o cambiar el código de estado. Es exactamente el conjunto de cambios que en producción rompería a alguien.

¿Para qué sirve el broker y el can-i-deploy?

El broker es una aplicación para compartir los contratos y los resultados de verificación. Resuelve un problema real: sin él, la información de qué versiones se probaron juntas y si pasaron queda repartida entre muchas ejecuciones de CI. El comando can-i-deploy es la consecuencia útil: antes de desplegar, preguntás si esa versión concreta es compatible con las versiones que ya están en el ambiente de destino, y el broker responde con los datos que tiene. Es la diferencia entre desplegar con información y desplegar con esperanza.

¿Reemplaza a las pruebas de integración?

No, y prometer eso es la forma más rápida de que la iniciativa fracase. El contract testing verifica la forma del intercambio: rutas, códigos de estado, estructura y tipos de los datos. No verifica la lógica de negocio, ni que los datos sean correctos, ni el rendimiento, ni que el flujo completo tenga sentido de punta a punta. Lo que hace bien es reemplazar la mayor parte de las pruebas de integración lentas que solo comprobaban que los servicios se entendieran, y dejar unas pocas pruebas de punta a punta para los flujos críticos.

Fuentes

Documentación oficial y material de la comunidad consultados para esta guía. Fecha de consulta: 27 de julio de 2026.

Aportes de la comunidad Underc0de

  1. Underc0de, foro. El mundo de las pruebas de API, sección QA y Testing, 23 de julio de 2024.
  2. Underc0de, foro. Testeo de APIs con Postman, por ANTRAX, 3 de octubre de 2021.
  3. Underc0de, foro. Corriendo colecciones de APIs con Newman y reporte en HTML, por ANTRAX, 22 de marzo de 2022.

Documentación oficial

  1. Pact. Documentación oficial. Definición de contract testing, roles de consumidor y proveedor, enfoque dirigido por el consumidor y «contrato por ejemplo», citados textualmente.
  2. Pact. How Pact works. Los cuatro pasos de la fase del consumidor, la generación del archivo de pacto y la verificación contra la respuesta mínima esperada.
  3. Pact. Pact Broker. Qué es el broker, el problema de información que resuelve, el comando can-i-deploy y el manejo de versiones, etiquetas y ramas.