Cómo validar APIs en un pipeline de CI/CD (1/2)

¿Por qué es necesario incluir API testing en el pipeline? El desarrollo software se trata de un proceso iterativo, más aún cuando se realiza en un enfoque “agile” en el que se entrega valor de manera incremental.

Cuando se desarrolla de esta manera, los cambios en los sistemas backend o el desarrollo de nuevas funcionalidades tardan en implementarse un cierto tiempo y los consumidores necesitan engancharse a esa funcionalidad lo antes posible para mostrar resultados.

Es en este punto donde las APIs ofrecen su mayor ventaja: exponer esa funcionalidad a los consumidores antes de que los servicios backend estén finalizados.

Con este enfoque se aumenta la agilidad del equipo permitiendo el desarrollo paralelo entre los desarrolladores de movilidad, frontend, terceros e incluso la generación de los tests de integración a la vez que el desarrollo en backend.

La automatización de pruebas con pipelines de integración continua ayudan a esa entrega de funcionalidad de una manera controlada, ofreciendo:

  • Mejora en los tiempos de reacción ante posibles errores al incorporar nuevas funcionalidades o cambiar la funcionalidad actual.
  • Reducción del riesgo al automatizar tareas repetitivas que consumen mucho tiempo al equipo.
  • Mejora de la productividad al poder dedicar el tiempo a tareas que no se pueden automatizar y dan valor al proyecto.

En un post anterior ya se habló en detalle sobre los beneficios del uso de pipelines de Jenkins en proyectos y las APIs como otro eslabón en la cadena del desarrollo y cómo deben incluirse dentro de estos flujos.

A nivel de herramientas de integración continua para APIs, generalmente se dividen en dos categorías:

  • Herramientas que ofrecen APIs para la ejecución de procesos de integración continua como un componente básico de dicha integración. Soluciones como Jenkins, TeamCity, Travis o Bambú permiten lanzar el proceso de compilación, despliegue y ejecución de tareas de manera automatizada a través de APIs que las propias herramientas incorporan.
  • Herramientas que ayudan a implementar integración continua para las APIs que se están desarrollando dentro de una organización, es decir, APIs de negocio.

Este post se centra en la segunda de las categorías, en concreto en herramientas que nos permitan tener un método automatizado para conseguir los siguientes objetivos:

  1. Garantizar que el software entregado cumple con la definición del contrato de la API y no rompe lo que actualmente está siendo consumido mediante los tests de contratos con Postman y Newman.
  2. Tener el control de los cambios que verdaderamente se están subiendo en la nueva versión mediante una librería de comparación de definición de APIs: swagger-diff.
  3. La definición de reglas de calidad del contrato y su cumplimiento mediante Speccy.

¿Qué necesitamos en nuestro pipeline?

Tests de contratos

Los test de contratos o de interfaz nos permiten verificar los esquemas de solicitud y de respuesta de una API y su comportamiento, es decir, qué información retorna un endpoint con diferentes solicitudes. Esta funcionalidad es especialmente útil en dos situaciones:

  • En aplicaciones en construcción en las que se siga la filosofía API First mediante el diseño y mockeado de los servicios, permitiendo a las aplicaciones consumidoras engancharse a estos servicios antes de que los backend estén construidos.

Con estos test, una vez las APIs pasen del mock a engancharse al servicio backend real, se puede probar de una manera automatizada la integración y detectar posibles desalineamientos que se hayan producido durante el desarrollo.

  • En aplicaciones en funcionamiento para comprobar flujos de funcionalidad críticos de una manera periódica en el pipeline y así minimizar las consecuencias de un fallo al detectarlos de forma reactiva.

A su vez, también pueden servirnos en el momento en que se quiera incorporar nuevas funcionalidades en una aplicación a modo de test de regresión para comprobar que todo sigue funcionando como hasta ahora.

Para generar estos tests se puede hacer uso de Postman y Newman siguiendo los siguientes pasos:

Definición del test de validación mediante JSON Schema

Para realizar los tests de contrato el primer paso es generar un JSON Schema con los cuerpos de petición y respuestas de las APIs.

Algunas herramientas como el gateway de AWS generan esos JSON Schema directamente desde el fichero de definición de contrato, Open API Specification (OAS, también conocido como Swagger).

También se pueden utilizar herramientas como jsonschema.net, que nos ayudan con esta tarea y evitar realizarlo a mano.

Postman es una de las aplicaciones más utilizadas para probar APIs. La mayoría de los desarrolladores escriben una prueba simple y verifican el resultado de la API.

Eso está bien para pruebas rápidas y con pocos casos de uso, pero cuando se requiere comprobar un flujo o se tiene un número elevado de casos de uso, es necesario automatizar todo ese proceso, además de gestionar diferentes entornos en cuyo caso la mejor opción es hacer uso del sandbox que vienen dentro de la herramienta junto con las variables de entorno.

Postman proporciona funcionalidades de testing mediante scripts basados en Node.js. Estos scripts nos permiten escribir un conjunto de pruebas para generar solicitudes con parámetros dinámicos, pasar datos entre solicitudes, validar esquemas, datos y un montón de verificaciones más. Estos scripts se dividen en dos categorías:

  • Los pre-request scripts: son fragmentos de código asociados a una solicitud que se ejecutan antes de que se envíe la petición al servidor, es decir, se ejecutan antes de probar el endpoint de la API.

Esta funcionalidad es útil para generar información necesaria de manera previa a la solicitud del endpoint. El caso más habitual es la generación de un token de acceso a la API. La obtención de dicho token es una funcionalidad perfecta para incluir dentro de los test previos al envío de la solicitud.

  • Los tests: se tratan de fragmentos de código que se ejecutan después de que la solicitud a la API se haya enviado y permiten acceder al objeto de respuesta de dicho endpoint.

La consola de test de Postman tiene el siguiente aspecto:

Tanto los tests de pre-solicitud como los tests posteriores se realizan de forma jerárquica en función del nivel en el que se hayan definido dentro de Postman: a nivel de colección, de carpeta o de solicitud siguiendo la siguiente secuencia:

En nuestro caso, para la validación del esquema de la respuesta de la API, se hace uso de los test a nivel de solicitud mediante la librería tv4, incluida en Postman.

Una posible propuesta para realizar una validación de un contrato a través de tv4, sería mediante las siguientes comprobaciones en cada petición:

  • Comprobar el código HTTP de respuesta que se espera:

  • Comprobar que el cuerpo de respuesta está presente o no según aplique, por ejemplo para un código 204 no hay cuerpo de respuesta:

  • Validar el esquema del cuerpo de respuesta con tv4 para lo cual hacen falta los siguientes pasos:
    • Definir un JSON Schema:

  • Validar el JSON Schema: en caso de que la respuesta se ajuste al esquema definido en el anterior paso el test daría Ok; y, en caso contrario, lanzaría un error en el que se loguea la causa del mismo.

En caso de recibir una respuesta correcta al ejecutar la petición tendríamos lo siguiente:

Un ejemplo de test que devuelve un error de validación es el siguiente:

Un error de validación de JSON Schema puede deberse a diferentes causas:

  • Que un atributo definido en el esquema no aparezca en la respuesta del JSON por parte del servidor, independientemente de si ese atributo es obligatorio o no.
  • Que la respuesta del JSON contenga un atributo no definido en el esquema. En este caso, se puede configurar que dé un error o no, aunque lo recomendable es que avise de esa discrepancia.
  • Que la estructura no se ajuste a la definida en el esquema, por ejemplo que en el esquema se tenga un objeto y se reciba como respuesta un array. Este es el caso de la captura de error anterior.

La documentación oficial con scripts de ejemplos para testear puede verse en detalle en la página oficial de Postman.

Variables de entorno

El siguiente paso, tras la implementación de los tests, es definir las variables de entorno para los mismos. En Postman, un entorno se trata de un conjunto de variables de tipo clave-valor.  

Dichos entornos permiten definir valores asociados a esas variables y que esos cambios se reflejen en las solicitudes de las APIs. En un entorno se pueden definir múltiples variables y se pueden utilizar múltiples entornos, pero en cada ejecución de tests sólo se hace uso de uno de dichos entornos y, por tanto, solo del conjunto de pares valor incluidos en él.

Para generar un entorno desde Postman se crea desde su consola y se añaden las variables con sus correspondientes valores de la siguiente forma:

Las valores asociados a las variables definidas dentro de un entorno pueden utilizarse tanto en las peticiones como en los scripts de los tests.

De esta forma se pueden definir tests válidos entre entornos, incluyendo en las variables aquella información que cambie entre ellos, por ejemplo el endpoint, la api-key o incluso en caso de que se tengan versiones de API desplegadas distintas en cada entorno, el JSON Schema correspondiente a cada versión.

Una vez se tienen definidos los tests y las variables de entorno asociados a los mismos se pueden ejecutar los tests a nivel de colección o carpeta dentro de la consola del producto con el “Runner” de la siguiente forma:

Obteniendo el siguiente resultado:

Exportación de los tests y variables de entorno

Si queremos lanzar las pruebas anteriores de una manera automatizada desde nuestro pipeline necesitamos exportar los archivos configurados en Postman.

Por un lado, las colecciones de tests y, por otro, las variables de entorno asociadas de las siguiente manera:

  • Exportación de la colección con los tests:

  • Exportación de las variables de entorno:

En este punto, una vez se hayan generado los tests y se hayan exportado, se tienen los siguientes ficheros:

  • El contrato con la definición de la API en sí, Open API Specification (OAS) en versión 2.0 o 3.0 según se decida.
  • La colección Postman en la que se incluyen todos los tests con la validación del contrato de cada petición, incluyendo por supuesto los cambios implicados en la nueva funcionalidad.
  • Los ficheros con las variables de entorno, en concreto uno para cada entorno de desarrollo.

Con este conjunto de ficheros que gestionamos dentro de un repositorio de código como Git, nos ayuda a tener un control total de los cambios y un histórico de los mismos.

Cuando se quiera añadir una funcionalidad nueva y se actualicen estos ficheros se abre una Pull Requests, que será el disparador de nuestro pipeline de integración continua en el que como primer paso se ejecutarán los tests incluidos en el repositorio, pero para realizar esa ejecución desde línea de comandos necesitamos Newman.

Ejecución de los tests con Newman vía línea de comandos

Newman se trata de una herramienta que permite ejecutar los tests definidos en Postman por línea de comandos, al igual que se haría mediante la propia aplicación como vimos antes.

Newman es fácilmente integrable en Jenkins, ya que está construido en Node.js, por lo que para su instalación es muy sencilla mediante npm siguiendo los pasos descritos aquí.

Para ejecutar los tests definidos en el archivo exportado desde Postman simplemente es necesario ejecutar el siguiente comando:

Siguiendo el ejemplo anterior tendríamos lo siguiente:

Conclusiones

Los tests de contratos constituyen la primera fase de nuestro flujo de validación de APIs dentro de nuestro pipeline de integración continua y su inclusión supone las siguientes ventajas:

  • Cerciorarse que la información proporcionada por los backend se corresponde con lo definido en el contrato y por tanto con lo que los consumidores esperan obtener con su uso.
  • Confirmar el comportamiento de nuestra API frente a los diferentes casos de uso que se puedan presentar, es decir, con las diferentes peticiones que puede recibir.
Foto de noeliamartin

Ingeniero Superior en Telecomunicaciones. Inicié mi carrera programando servicios hasta llegar al mundo de las APIs. Actualmente trabajo en Paradigma en el departamento de Arquitectura dentro del área de API Management y gobierno intentando promover las buenas prácticas en diseño y desarrollo de las APIs.

Ver toda la actividad de Noelia Martín

Escribe un comentario