Blog

Contract Testing: Qué Es y Cómo Implementarlo con Pact

Blog
Conocé cómo podés garantizar la interoperabilidad entre sistemas distribuidos y ahorrate los dolores de cabeza con este nuevo enfoque.
Contract Testing: Qué Es y Cómo Implementarlo con Pact


La forma más sencilla de entender el contract testing, o pruebas de contrato en español, es detenernos en una de las palabras clave que conforman a esta metodología, siendo esta palabra “contrato”. Cuando hablamos de un contrato, nos referimos, en términos generales, a un pacto entre partes donde se establecen compromisos y obligaciones. Las pruebas por contrato toman este concepto y lo adaptan al desarrollo de software, permitiéndonos definir y validar expectativas para asegurar una comunicación precisa entre servicios.

Contract Testing vs End-to-end

Algo que puede ayudarnos a terminar de entender qué son las pruebas de contrato, es el ponerlo en contraposición con un enfoque algo más conocido, las pruebas end-to-end.

Las pruebas end-to-end implican desplegar todos los componentes de un sistema en un entorno con características similares a la producción y ejecutar una serie de pruebas contra ellos. Aunque las pruebas end-to-end nos brindan gran confianza en el funcionamiento del sistema al evaluar el proceso completo, presentan desventajas, como su lentitud y la imposibilidad de ejecutarlas en paralelo. Además, debido a su «fragilidad», incluso pequeños errores de configuración en los entornos pueden hacer que estas pruebas fallen.

Por otro lado, las pruebas de contrato surgen como una metodología diferente de las pruebas end-to-end, enfocada en garantizar la compatibilidad entre sistemas separados, como los microservicios, con el objetivo de garantizar una comunicación eficiente. Mediante estas pruebas, capturaremos las interacciones entre cada servicio en un contrato y posteriormente verificaremos que cada parte pueda cumplir con él. De esta forma, en lugar de desplegar todo el sistema, podemos centrarnos individualmente en cada participante de la integración.

Antes de continuar adentrándonos en esta metodología, y específicamente en la herramienta Pact, es importante comprender el concepto de proveedores y consumidores, ya que nos referiremos a los distintos participantes del sistema utilizando estos términos.

En la arquitectura de servicios web, los proveedores son aquellos que ofrecen datos o funcionalidad a través de la web, como las APIs. Por otro lado, los consumidores son las aplicaciones que utilizan estos datos o funcionalidades.

Explorando Pact

Pact es una potente herramienta de código abierto que facilita la prueba de integraciones HTTP y de mensajes mediante pruebas de contrato. Permite probar de manera segura y eficiente sistemas distribuidos.

Se utiliza para la comunicación mensajes en formato JSON a través de protocolos como HTTP o colas de mensajería. Resulta útil en diversas situaciones, como pruebas de sitios web y backends, aplicaciones web React, aplicaciones móviles nativas y microservicios RESTful.

Pact también ofrece una serie de elementos o herramientas que pueden enriquecer nuestra experiencia con las pruebas por contrato. Estos elementos permiten compartir los contratos, visualizarlos e incluso integrar Pact en nuestro flujo de CI/CD para evaluar si es seguro desplegar nuestras aplicaciones de manera conjunta. A continuación, veremos estos aspectos.

El Rol del Pact Broker

Dentro de los componentes de Pact, encontraremos el Pact Broker, una herramienta de código abierto que permite compartir contratos y resultados de verificación, siendo esencial para la integración de Pact en flujos de trabajo CI/CD. Esta necesita ser desplegada, administrada y alojada por el usuario.

Proporciona ejemplos reales de las interacciones y relaciones entre los servicios participantes, documentación actualizada de las API, solución para compartir contratos y resultados de verificación entre consumidores y proveedores, integración en flujos de trabajo CI/CD, e indica qué versiones de las aplicaciones pueden ser desplegadas de manera segura en conjunto.

Documentación: https://docs.pact.io/

PactFlow

PactFlow es un servicio manejado basado en un fork propietario del Pact Broker de código abierto que ofrece una interfaz de usuario mejorada, resultados de verificación a nivel de campo y gestión de usuarios y equipos.

Todos los planes de PactFlow incluyen el alojamiento del Pact Broker y vienen con beneficios y capacidades adicionales.

PactFlow cuenta con una sección dedicada para la herramienta “can-i-deploy”, con una interfaz de usuario completa que facilita la consulta de la matriz. Esto asegura despliegues seguros y proporciona un contexto adicional que no es fácilmente disponible al utilizar la interfaz de línea de comandos.

https://pactflow.io/

Herramienta “can-i-deploy”

La herramienta de Pact, “can-i-deploy” es usada para determinar si es seguro desplegar una aplicación basada en la versión actual del pacto publicado, esto ayuda a los equipos a no cometer el error de desplegar una nueva versión que pueda romper el contrato existente. Utilizando la herramienta podremos verificar la compatibilidad de un proveedor y un consumidor basados en su contrato, si sus interacciones son correctas, la herramienta nos devolverá un mensaje de éxito, y si han ocurrido cambios que rompen el contrato, un mensaje de error.

Ejemplo de Uso

En este ejemplo, imaginemos que debemos implementar Pact sobre un sitio web construido en React, diseñado para ofrecer pronósticos climáticos a los usuarios. Llamaremos a este «WeatherForecastWeb». Para obtener datos climáticos, la web se integra con un servicio denominado «WeatherDataService», desarrollado utilizando NestJS. En este contexto, «WeatherForecastWeb» actúa como el consumidor, mientras que «WeatherDataService» tiene el papel de proveedor.

Generalmente, sin las pruebas de contrato, lanzaríamos ambas aplicaciones, haríamos una solicitud desde el consumidor hacia el proveedor y verificaríamos su correcto funcionamiento. Sin embargo, este enfoque puede complicarse si el proveedor tiene sus propias dependencias, ya que también tendríamos que levantar esos servicios para verificar su funcionamiento.

Usando Pact, este proceso es más simple, ya que solo necesitamos probar una aplicación a la vez. Esto podemos lograrlo en tres pasos:


1. Testear al consumidor:

Para lograr esta tarea, vamos a comenzar instalando las dependencias necesarias, dependiendo del lenguaje, la forma de instalación y el nombre de la librería puede variar, por lo que te recomiendo revisar la documentación para tu lenguaje elegido en pact.io. En el caso de este ejemplo, estaremos utilizando @pact-foundation/pact

Luego, deberemos configurar Pact especificando el nombre de nuestro par de aplicaciones, nivel de log y directorio donde queremos guardar los contratos, entre otras cosas.

Contract Testing: Qué Es y Cómo Implementarlo con Pact


Finalmente vamos a definir las expectativas definiendo las interacciones esperadas, debajo un ejemplo:

Contract Testing: Qué Es y Cómo Implementarlo con Pact


Repetiremos este proceso para cada interacción de nuestro sistema. Testeando el Consumidor

2. Subimos el contrato generado por nuestro consumidor a un broker, ya sea el broker de código abierto o PactFlow:

Dependiendo de si utilizamos el broker open source o PactFlow puede haber algunas diferencias en la subida del pacto, lo que veremos a continuación es un pequeño ejemplo de script que puede ser ejecutado (por ejemplo a través de un script en nuestro package.json) que se va a encargar de subir nuestros pactos al broker open source.

Contract Testing: Qué Es y Cómo Implementarlo con Pact


Utilizando este broker, la vista principal se vería de esta forma, listando cada uno de nuestros contratos para cada par de aplicaciones consumer / provider:

Contract Testing: Qué Es y Cómo Implementarlo con Pact


Pact Broker Dockerizado


3. Escribimos las pruebas de verificación en nuestro proveedor:

Para estas obtendremos los contratos del broker y verificaremos que podamos cumplir con las expectativas definidas por el consumidor. Replicamos las solicitudes definidas contra el proveedor y verificamos que responda correctamente. La verificación comprueba todos los detalles de la respuesta, como las cabeceras, el cuerpo, el estado, etc., asegurándose de que cumplan con lo esperado.
Este código es un poco más largo y lo vas a poder encontrar hosteado en Github en el siguiente enlace:

https://gist.github.com/

Tener en cuenta que si tenemos la necesidad de testear una petición para la cual necesitamos que exista data en nuestro proveedor, podremos utilizar “Provider States” los cuales nos permiten setear un estado de la aplicación antes de que las interacciones se ejecuten. Esto podemos hacerlo de múltiples formas, siendo una de estas el comunicarnos con una base de datos en memoria e insertar los datos necesarios para ejecutar el test. Para más información puede leerse en siguiente artículo:

https://docs.pact.io/getting_started/provider_states

Adicionalmente, es importante leer la documentación para poder adaptar nuestras pruebas de verificación a lo que necesitemos, es probable que tengan que jugar con los selectores de versión u otra de las configuraciones dadas por Pact.

Testeando el Proveedor

Siguiendo estos pasos y haciendo uso de las variadas herramientas que ofrece Pact, lograremos establecer un robusto proceso de pruebas que asegure una comunicación exitosa en nuestros sistemas.

¿Quedaron dudas?

Cómo funciona Pact
Introducción al Contract Testing con PactFlow
«Guía de 5 minutos»
Proveedor de Ejemplo en JavaScript
Consumidor de Ejemplo en JavaScript

Contacto

Contactanos

¿Cómo podemos ayudarte?