Logotipo de Parasoft

¡Descubre GoogleTest, con certificación TÜV y la tecnología Agentic AI para pruebas de C/C++!
Obtenga los detalles »

Fondo geométrico con toques de azul y verde.
Imagen de portada del documento técnico "Patrones de prueba para microservicios"

White Paper

Patrones de prueba para microservicios

Antes de empezar, consulta los puntos clave de nuestro informe técnico a continuación.

Noticias

Como arquitectura para la construcción de sistemas complejos, los microservicios están ganando terreno significativamente en la comunidad de desarrolladores. Si bien se empieza a comprender que no son la solución definitiva para todos los problemas de arquitectura de aplicaciones, aquellas que comparten desafíos relacionados con las dependencias y la escalabilidad pueden beneficiarse enormemente de ellos.

Con el auge de los microservicios, comprender cómo probarlos se convierte en un desafío. Probar las interfaces entre servicios es complejo. Sin embargo, existe una forma eficaz de probar las API que mejora las implementaciones de microservicios.

En algunas formas, Probando una aplicación de microservicios No es diferente a probar una aplicación construida con cualquier otra arquitectura. Los microservicios utilizan tecnologías bien conocidas, como REST o colas, para las cuales la industria ya cuenta con herramientas de prueba y mejores prácticas bien establecidas.

El principal desafío de los microservicios reside en la gran cantidad de servicios que componen una aplicación, así como en las dependencias entre ellos. Además, cada microservicio debe seguir funcionando correctamente incluso cuando los demás microservicios de los que depende no estén disponibles o presenten fallos de respuesta.

Este documento técnico explora estrategias de prueba para arquitecturas de microservicios, abarcando patrones de orquestación y coreografía, enfoques de virtualización de servicios y mejores prácticas para crear pruebas automatizadas en sistemas distribuidos complejos.

Comprender los patrones de microservicios

El primer paso para comprender las pruebas de microservicios es tener un conocimiento común de los patrones de mensajería habituales que describen su comportamiento.

Los principios fundamentales de los microservicios se basan en que son servicios discretos y ligeros que se ejecutan como procesos individuales desplegables, utilizando la tecnología que el equipo considere óptima para su proyecto. Estos microservicios suelen agruparse en funciones y dominios empresariales, cuya composición de componentes representa el sistema bajo prueba.

Los microservicios suelen seguir dos patrones. al interactuar entre sí:

  • Orquestación
  • Reactivo (coreografía)

Muchos microservicios utilizan un enfoque híbrido combinado. En este documento, describimos algunos de los desafíos que surgen al crear pruebas automatizadas para microservicios que utilizan estos diferentes patrones y proporcionamos estrategias para abordar esos desafíos. Nos centraremos en las pruebas para microservicios individuales en lugar de pruebas de extremo a extremo de toda la aplicación.

Patrón de orquestación

Un microservicio que utiliza orquestación realiza una o más llamadas explícitas a servicios externos o dependencias. Estas llamadas suelen emplear un flujo síncrono de solicitud-respuesta y, a menudo, acceden a servicios basados ​​en REST. Si los servicios deben invocarse en un orden específico, las llamadas a un servicio posterior no se realizan hasta que se recibe una respuesta a una llamada a un servicio anterior. Debido a que un servicio llama explícitamente a otro, están estrechamente acoplados.

Diagrama: Servicio de cartera con flechas bidireccionales hacia los servicios de Cuentas y Cotizaciones, Cotizaciones conectadas a Precios de acciones externos

En este ejemplo, el servicio de Cartera realiza un seguimiento de las posiciones bursátiles de un usuario. Al añadir una posición a la cartera, el servicio de Cartera llama al servicio REST de Cuentas para asegurarse de que el usuario dispone de fondos suficientes en su cuenta. Tras la respuesta de la llamada a Cuentas, llama al servicio REST de Cotizaciones para consultar el precio actual de la acción. Una vez que la llamada a Cotizaciones finaliza, el servicio de Cartera puede completar la tarea de añadir la nueva posición.

Desafíos de prueba

Creación y ejecución de pruebas

Crear y ejecutar pruebas para el microservicio Portfolio resulta complicado por las siguientes razones:

  • El microservicio Portfolio tiene dependencias con los microservicios Accounts y Quotes, que deben implementarse en el entorno de prueba junto con el microservicio Portfolio, pero el equipo que está desarrollando el microservicio Portfolio puede no ser el mismo que está desarrollando los otros dos microservicios.
  • El servicio de cotizaciones depende de un servicio de terceros para obtener precios de acciones en tiempo real, y los datos que devuelve dicho servicio cambian constantemente. Para realizar una prueba estable del servicio de cartera, los datos que devuelve el microservicio de cotizaciones deben ser constantes.
  • Es necesario probar comportamientos inesperados del servicio de Portafolio, como cuando los servicios de Cuentas o Cotizaciones no están disponibles, responden lentamente o devuelven datos inesperados. Es importante poder simular diferentes tipos de comportamientos inesperados en estos servicios para validar que el microservicio de Portafolio gestiona correctamente las condiciones de error.

Una solución consiste en utilizar la virtualización de servicios para simular las respuestas de los microservicios de Cuentas y Cotizaciones. solución de virtualización de serviciosLas herramientas como Parasoft Virtualize permiten definir versiones virtuales de los microservicios Cuentas y Cotizaciones, e implementarlas junto con la instancia real del microservicio Portafolio. La virtualización de microservicios es similar a la virtualización de cualquier otro tipo de arquitectura de servicio o aplicación.

Diagrama: Servicio de cartera (real) conectado a los servicios virtuales de Cuentas y Cotizaciones con iconos de virtualización.

Una vez hecho esto, el microservicio Portfolio se puede probar independientemente de sus dos dependencias.

Configuración de diferentes entornos para diferentes casos

El siguiente desafío consiste en configurar distintos entornos para diferentes casos, como cuando los servicios de Cuentas y Cotizaciones presentan comportamientos esperados e inesperados. Supongamos que el equipo desea probar cómo se comporta el servicio de Portafolio cuando el servicio de Cuentas o el de Cotizaciones responden lentamente o generan errores. Esto podría requerir la ejecución de al menos cinco conjuntos de pruebas diferentes, cada uno con una configuración de entorno distinta.

Ejecutar prueba Configuración del servicio de cuentas Configuración del servicio de cotizaciones
Comportamiento normal Comportamiento normal Comportamiento normal
Tiempo de respuesta lento de las cuentas Responde lentamente Comportamiento normal
Respuestas de error de cuentas Responde con errores Comportamiento normal
El tiempo de respuesta de las cotizaciones es lento. Comportamiento normal Responde lentamente
Respuestas de error de citas Comportamiento normal Responde con errores

Para cada ejecución de prueba, es necesario configurar correctamente el entorno antes de poder ejecutar las pruebas correspondientes. En este ejemplo, obtenemos al menos cinco ejecuciones de prueba diferentes, cada una con su propia configuración de entorno. El módulo Environment Manager de Parasoft CTP (Plataforma de Pruebas Continuas) permite gestionar estas distintas configuraciones de entorno.

Diagrama: Entorno de prueba de portafolio que muestra el menú desplegable Seleccionar instancias con opciones de configuración y conexiones de servicio.

Lo que hemos descrito en este ejemplo no es exclusivo de una arquitectura de microservicios. Problemas similares surgen en arquitecturas orientadas a servicios en general, así como en aplicaciones monolíticas que pueden depender de solo unos pocos servicios. Sin embargo, en una arquitectura de microservicios, el número de servicios dependientes aumenta significativamente. En este sencillo ejemplo con solo tres microservicios, ya podemos observar que el número de configuraciones de entorno diferentes puede incrementarse rápidamente al intentar probar distintos estados de la aplicación. En un entorno de microservicios con decenas o cientos de servicios, la capacidad de crear, gestionar y alternar programáticamente entre diferentes configuraciones de entorno para distintos escenarios de prueba es fundamental.

Los efectos de los cambios en la API

A medida que los equipos evolucionan sus microservicios, es inevitable que se realicen cambios en las API de los servicios. Un problema clave que surge con estos cambios es cómo comprender su impacto en los usuarios de los servicios. La industria ha estado adoptando las pruebas de contrato como solución a este problema. Sin embargo, ha surgido un problema menos conocido relacionado con los cambios en las API: cómo actualizar de manera eficiente los escenarios de prueba y los activos virtuales dentro de la infraestructura de pruebas para reflejar las API actualizadas.

Cuando un equipo modifica la API de un microservicio que está desarrollando, las pruebas que validan dicho microservicio deben actualizarse en función de los cambios en la API. Del mismo modo, si se utilizan servicios virtuales para simular microservicios dependientes y la API de uno de ellos cambia, los servicios virtuales del microservicio dependiente deben actualizarse para reflejar dichos cambios en la API.

Muchos equipos utilizan OpenAPI, RAML u otra definición de servicio para describir las API de sus microservicios. Al usar definiciones de servicio, el módulo Change Advisor de Parasoft SOAtest y Parasoft Virtualize detecta automáticamente qué API han cambiado y refactoriza automáticamente las pruebas funcionales o los servicios virtuales existentes para actualizarlos con los campos nuevos o eliminados de la API. Los equipos pueden crear versiones actualizadas de sus definiciones de servicio y usar Change Advisor para comprender el impacto de los cambios en sus pruebas y servicios virtuales antes de implementarlos. Una vez realizados los cambios, Change Advisor permite actualizar de forma rápida y sencilla los recursos existentes para reflejar las modificaciones en los microservicios.

Patrón reactivo (coreografía)

Uno de los objetivos principales de una arquitectura de microservicios es crear componentes independientes. De esta forma, el despliegue, el escalado y la actualización de los servicios resultan más sencillos. Sin embargo, este objetivo no se alcanza por completo al utilizar el patrón de orquestación, ya que los microservicios individuales tienen dependencias directas entre sí. Una solución a este problema es el patrón de coreografía, también conocido como microservicios reactivos o basados ​​en eventos. En este patrón, los microservicios no se referencian directamente entre sí. En su lugar, envían mensajes a flujos de eventos a los que otros microservicios se han suscrito.

Diagrama: Servicios de cartera y cuentas conectados mediante flujos de eventos de posición añadida y cuenta actualizada con líneas punteadas.

En este ejemplo, supongamos que el servicio de Cartera ha recibido instrucciones para agregar una posición en acciones. En lugar de llamar directamente al servicio de Cuentas, publica un evento en el flujo de eventos "Posición agregada". El microservicio de Cuentas está suscrito a dicho flujo de eventos, por lo que recibe la notificación. Comprueba que el usuario tenga fondos suficientes en su cuenta. Si es así, reduce el saldo y publica un evento en el flujo de eventos "Cuenta actualizada". Si el usuario no tiene fondos suficientes, puede publicar un evento de error en otro flujo de eventos (no se muestra para simplificar el ejemplo). El microservicio de Cartera está suscrito al flujo de eventos "Cuenta actualizada" y, al recibir el evento del microservicio de Cuentas, actualiza su cartera según la confirmación recibida.

La comunicación asíncrona en este tipo de arquitectura ofrece la ventaja de que los servicios están altamente desacoplados entre sí: las instancias de cada servicio pueden reemplazarse, redistribuirse o escalarse sin que los demás microservicios se vean afectados. La desventaja es que la naturaleza asíncrona de los eventos dificulta la comprensión de cómo se ejecutará el sistema y cuál será el flujo de eventos. Dependiendo del orden o el tipo de eventos que se produzcan, el sistema podría comportarse de maneras inesperadas. Esto se conoce como comportamiento emergente y representa un desafío inherente en el desarrollo y las pruebas de microservicios coreografiados.

Existen diferentes patrones de mensajería asíncrona que se engloban dentro de la categoría más amplia de microservicios basados ​​en eventos.

Llamadas de comandos asíncronas

El patrón de llamadas de comandos asíncronas se utiliza cuando se requiere orquestar microservicios mediante acciones asíncronas, donde un microservicio necesita llamar a otro de forma asíncrona, garantizando que este último reciba el mensaje. En este patrón, los mensajes se intercambian normalmente mediante colas. Un framework común utilizado en arquitecturas de microservicios para implementar este patrón es RabbitMQ.

Un ejemplo concreto de este patrón se da cuando un microservicio necesita publicar un evento para que un segundo microservicio lo procese y, a continuación, esperar a recibir una respuesta de dicho segundo microservicio. Este comportamiento se describió anteriormente al presentar el patrón de coreografía de microservicios.

Diagrama: Servicios de cartera y cuentas conectados mediante flujos de eventos de posición añadida y cuenta actualizada con líneas punteadas.

En este ejemplo, una llamada a la API REST le indica al microservicio Portfolio que agregue una posición. El servicio Portfolio publica un evento en la cola Position Added para que el microservicio Accounts lo procese, y luego espera a que Accounts publique un evento de respuesta en la cola Account Updated para que la llamada a la API REST pueda devolver los datos recibidos de dicho evento. Existen dos maneras diferentes de configurar un escenario de prueba para este ejemplo.

  1. Cree un entorno con las colas necesarias donde el servicio Portfolio esté implementado, pero el servicio Accounts no. Dado que el servicio Accounts no está implementado, el escenario de prueba deberá simular su comportamiento publicando el evento esperado en el momento adecuado. Se creará un escenario de prueba de Parasoft SOAtest con dos pruebas.
    • Ejecutar la API REST del servicio Portfolio.
    • Publica el evento desde el servicio de Cuentas.

Es necesario configurar las pruebas para que se ejecuten simultáneamente, de modo que el evento del servicio Cuentas se publique mientras el servicio Cartera esté a la espera de dicho evento.

  1. En lugar de simular el servicio Cuentas mediante una prueba que publique su evento, puede ser útil crear un servicio virtual reutilizable que escuche los eventos publicados en la cola de Posición Añadida y publique el evento resultante en la cola de Cuenta Actualizada. Este microservicio virtual sería reutilizable en diversos escenarios de prueba que lo requieran.

El primer enfoque es sencillo y crea un recurso de prueba autónomo que no depende de infraestructuras externas adicionales. El segundo enfoque es reutilizable y simula con mayor precisión el comportamiento real del sistema. Sin embargo, este segundo enfoque implica el costo de construir, implementar y administrar un recurso virtual independiente.

Una variante de este patrón consiste en un microservicio que escucha en una cola la llegada de un evento, lo procesa y, a continuación, publica un evento de seguimiento en una cola diferente para que uno o más microservicios lo procesen.

Diagrama: Pagos → Pago procesado → Factura → Factura creada → Cadena de servicio de correo electrónico

En este ejemplo, el microservicio Factura es el que se debe probar. El servicio Pagos publica un evento en la cola de RabbitMQ Pago Procesado para que el servicio Factura lo recoja. El microservicio Factura lee el evento de la cola, crea una factura y luego publica un evento en la cola Factura Creada para que el microservicio Correo Electrónico envíe un correo electrónico al cliente con la factura.

Para crear un escenario de prueba para el microservicio Facturación, se configura un entorno de prueba que contiene dos colas de RabbitMQ y el microservicio Facturación implementado. Utilizando el transporte personalizado de RabbitMQ incluido en el paquete IoT/Microservicios de Parasoft Marketplace, se construye un escenario de prueba de Parasoft SOAtest que publica un evento de pago procesado en la cola de Pagos Procesados. A continuación, el escenario se suscribe a la cola de Facturación Creada para validar que el servicio Facturación publique el evento de creación de factura correcto como respuesta.

Manguera de bomberos para eventos

El patrón de flujo de eventos se utiliza cuando diferentes fuentes generan una gran cantidad de eventos que deben entregarse rápidamente a distintos consumidores a través de un hub común. En este patrón, los mensajes se intercambian mediante temas, mientras que en el patrón de llamadas de comandos asíncronas, mencionado anteriormente, se intercambian mediante colas. Un framework común para implementar este patrón es Apache Kafka.

Diagrama: Centro Kafka con múltiples servicios web conectados en los lados izquierdo y derecho.

Digamos que queremos probar un único microservicio que se suscribe a un tema de Kafka, procesa los eventos que recibe y luego publica sus resultados en un segundo tema de Kafka.

Diagrama: Datos meteorológicos → Servicio de pronóstico → Datos de pronóstico

En este ejemplo, tenemos un microservicio de pronóstico que se suscribe a un tema de datos meteorológicos que recopila gran cantidad de datos meteorológicos de diversas fuentes. Luego, procesa esos datos para actualizar su modelo de pronóstico y publica los datos de pronóstico en el tema de datos de pronóstico. En este caso, necesitamos validar que el servicio de pronóstico publique los eventos esperados en el tema de datos de pronóstico para un conjunto específico de eventos de datos meteorológicos. Esto se lograría configurando un entorno de prueba con los dos temas de Kafka y el servicio de pronóstico implementado.

Construiríamos un escenario de prueba utilizando Parasoft SOAtest y el transporte personalizado de Kafka incluido en el paquete IoT/Microservices de la Mercado de Parasoft. El escenario de prueba consistiría primero en publicar los eventos necesarios en el tema Datos meteorológicos y, a continuación, suscribirse al tema Datos de pronóstico para verificar que el servicio de pronóstico publicara los eventos de datos de pronóstico correctos. Sería necesario crear varios escenarios de prueba diferentes para verificar los distintos tipos y el orden de los eventos que se espera que gestione el microservicio de pronóstico.

Este es un escenario de prueba relativamente sencillo. El hecho de que el microservicio Forecast esté desacoplado de los demás microservicios tiene la ventaja de que la prueba para el servicio Forecast también lo esté. En este caso, no es necesario configurar un entorno complejo con servicios virtuales. Simplemente se pueden crear escenarios de prueba que publiquen eventos y verificar que se generen los eventos correctos en respuesta.

Configuración de entornos de prueba

Muchos equipos de microservicios han adoptado un proceso de CI/CD para la creación, prueba y despliegue de microservicios en contenedores, con el fin de automatizar el proceso y reducir los riesgos asociados al despliegue de actualizaciones. En este proceso, se crea automáticamente una imagen de contenedor que contiene el microservicio y se despliega en un entorno de prueba, generalmente administrado por Kubernetes o una distribución basada en Kubernetes como OpenShift, donde el microservicio se puede validar antes de su implementación en pruebas de extremo a extremo y, finalmente, en producción.

Hemos visto que la virtualización de servicios es útil e incluso esencial para crear escenarios de prueba de microservicios. Cuando los entornos de prueba se basan en tecnologías como Docker o Kubernetes, las herramientas utilizadas para crear e implementar servicios virtuales deben integrarse perfectamente en dichos entornos. Servicios virtuales Deben estar altamente modularizados y ser fácilmente implementables por las mismas razones que los microservicios que simulan. Sin embargo, los proveedores tradicionales de virtualización de servicios no satisfacen esta necesidad debido a que las aplicaciones son monolíticas, centralizadas y utilizadas por múltiples equipos.

Para que la virtualización de servicios funcione en estos entornos, es necesario crear servicios virtuales en contenedores que se puedan implementar fácilmente. Para crear un servicio virtual en contenedores, se toma una imagen base que contiene Virtualización de Parasoft y todas sus dependencias, y superponerla con otra imagen que contenga todas las configuraciones de activos virtuales para el servicio virtual. La nueva imagen para el servicio virtual se implementaría como un contenedor en el entorno Docker/Kubernetes junto con el contenedor para el microservicio bajo prueba y todas sus dependencias (virtualizadas).

Resumen

Los patrones de mensajería y los patrones de prueba asociados que se discuten en este documento no son nuevos, pero la necesidad de usar estos patrones ha crecido significativamente a medida que los microservicios se vuelven más comunes y más aplicaciones adoptan un paradigma de microservicios. SOAtest, Virtualize y de Parasoft CTP Permite a los equipos crear e implementar escenarios de prueba para microservicios con la máxima flexibilidad, garantizando así la alta calidad y fiabilidad de sus microservicios.

¿Listo para sumergirte más profundamente?

Obtenga el documento técnico completo