X
BLOG

Cómo abordar las pruebas de microservicios

Cómo abordar las pruebas de microservicios Tiempo de leer: 11 minutos
En muchos sentidos, probar una aplicación de microservicios no es diferente a probar una aplicación creada con cualquier otra arquitectura. El desafío único de los microservicios es la gran cantidad de servicios que componen una aplicación, junto con la cantidad de dependencias entre los servicios.

Como arquitectura para construir sistemas complejos, los microservicios están ganando una tracción significativa dentro de la comunidad de desarrollo. Si bien la gente comienza a comprender que no es una panacea para todos los problemas de arquitectura de aplicaciones, las aplicaciones que comparten desafíos relacionados con las dependencias y el escalado pueden beneficiarse enormemente de ella.

La adopción de microservicios va en aumento, pero también lo son las luchas asociadas con la comprensión de cómo probar microservicios. Toby Clemson de ThoughtWorks ha hecho un gran trabajo enumerando estrategias de prueba que quizás desee emplear en una arquitectura de microservicios (consulte su artículo para obtener una excelente descripción general de los diferentes tipos de pruebas que puede querer crear), pero el conocimiento general sobre cómo construir y mantener esos diferentes tipos de pruebas aún está en pañales .

Pero, en muchos sentidos, probar una aplicación de microservicios no es diferente a probar una aplicación creada con cualquier otra arquitectura. Los microservicios utilizan tecnologías conocidas, como REST o colas, para las cuales la industria del software ya cuenta con herramientas de prueba bien establecidas y mejores prácticas. El desafío único de los microservicios es la gran cantidad de servicios que componen una aplicación, junto con las dependencias entre los servicios. Además, cada microservicio aún debe funcionar correctamente, incluso cuando otros microservicios de los que dependen no están disponibles o responden incorrectamente.

Los microservicios suelen seguir dos patrones cuando interactúan entre sí: orquestación y reactivo (coreografía). Muchos microservicios utilizan un enfoque "híbrido" combinado. En esta publicación, proporcionaré algunas estrategias para abordar algunos de los desafíos que surgen al crear pruebas automatizadas para microservicios que utilizan estos diferentes patrones, centrándome en las pruebas para los microservicios individuales (a diferencia de las pruebas de un extremo a otro de toda la aplicación). ).

Prueba de microservicios orquestados

Un microservicio que utiliza la orquestación realizará una o más llamadas explícitas a dependencias o servicios externos. Las llamadas suelen utilizar un flujo de solicitud-respuesta síncrono y, a menudo, accederán a servicios basados ​​en REST. Si es necesario llamar a los servicios en un orden específico, las llamadas a un servicio posterior no se realizan hasta que se recibe una respuesta para una llamada a un servicio anterior. Debido a que un servicio llama explícitamente a otro, están estrechamente acoplados.

En el ejemplo que se muestra arriba, crear y ejecutar pruebas para el microservicio de Portafolio es un desafío porque el microservicio de Portafolio tiene dependencias en los microservicios de Cuentas y Cotizaciones, que deben implementarse en el entorno de prueba junto con el microservicio de Portafolio. El servicio Cotizaciones depende de un servicio de terceros para recuperar los precios de las acciones en tiempo real, y los datos devueltos por ese servicio siempre cambian.

Confiar en servicios de terceros o servicios desarrollados por diferentes equipos aumenta enormemente la complejidad del entorno de prueba. Además, es necesario probar cualquier comportamiento inesperado del servicio de Cartera, como cuando los servicios de Cuentas y / o Cotizaciones no están disponibles, responden lentamente o responden con datos inesperados. Es importante poder hacer que esos servicios respondan con diferentes tipos de comportamiento inesperado para validar que el microservicio Portfolio maneja las condiciones de error correctamente.

Cómo simplificar las pruebas de arquitecturas de microservicios

¡Virtualización de servicios al rescate!

Puedes usar virtualización de servicios para simular las respuestas de los microservicios de Cuentas y Cotizaciones. La virtualización de servicios le permite definir versiones virtuales de los microservicios de Cuentas y Cotizaciones e implementarlas junto con la instancia real del microservicio de Cartera. Virtualizar microservicios es similar a virtualizar cualquier otro tipo de arquitectura de servicio o aplicación. Podría verse así:

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

El siguiente desafío es configurar diferentes entornos para diferentes casos, como cuando los servicios de Cuentas y Cotizaciones exhiben comportamientos esperados e inesperados. Digamos que el equipo quiere probar cómo se comporta el servicio de Cartera cuando el servicio de Cuentas o el servicio de Cotizaciones responde lentamente o responde con condiciones de error. Esto puede requerir la ejecución de al menos 5 conjuntos diferentes de pruebas, cada uno de los cuales tiene una configuración de entorno diferente teniendo en cuenta los tiempos de respuesta lentos, las respuestas de error y el comportamiento normal y anormal de los servicios dependientes.

Para cada ejecución de prueba, es necesario poner el entorno en la configuración correcta antes de que se puedan ejecutar las pruebas para esa configuración. En este ejemplo, terminamos con al menos cinco ejecuciones de prueba diferentes, cada una de las cuales tiene su propia configuración para el entorno. El módulo Environment Manager dentro de Parasoft Plataforma de prueba continua puede gestionar estas diferentes configuraciones de entorno por usted:

Este proceso no es específico de una arquitectura de microservicios; los mismos tipos de problemas surgen en las arquitecturas orientadas a servicios en general, así como en las aplicaciones monolíticas que pueden depender solo de unos pocos servicios. En una arquitectura de microservicios, sin embargo, la cantidad de servicios dependientes aumenta significativamente. En un entorno de microservicios con decenas o cientos de servicios, la capacidad de crear, administrar y cambiar mediante programación entre diferentes configuraciones de entorno para diferentes escenarios de prueba es muy importante y proporciona una reducción significativa de tiempo y esfuerzo.

Gestión de cambios de API en microservicios orquestados

A medida que los equipos evolucionan sus microservicios, es inevitable que se realicen cambios en la API en los servicios. Un problema clave que surge con los cambios de API es cómo comprender el efecto de esos cambios en los consumidores de los servicios.

Cuando un equipo modifica la API para un microservicio que está creando, cualquier prueba que valide ese microservicio debe actualizarse en función de los cambios en la API. Por el contrario, si se utilizan servicios virtuales para simular microservicios dependientes y una API para uno de esos cambios de microservicios dependientes, los servicios virtuales para el microservicio dependiente deben actualizarse para reflejar los cambios en la API.

Muchos equipos usan OpenAPI, RAML u otra definición de servicio para describir las API de sus microservicios. Cuando se utilizan definiciones de servicio, el módulo Asesor de cambios dentro Parasoft SOAtest y Parasoft Virtualize puede detectar automáticamente qué API han cambiado y luego refactorizar automáticamente las pruebas funcionales existentes o los servicios virtuales para actualizarlos con cualquier campo nuevo o eliminado en la API. Los equipos pueden crear versiones actualizadas de sus definiciones de servicio y utilizar el Asesor de cambios para comprender el impacto de los cambios en sus pruebas y servicios virtuales antes de realizar los cambios. Una vez que se realizan los cambios, Change Advisor hace que sea rápido y sencillo actualizar los activos existentes para reflejar los cambios dentro de los microservicios.

Prueba de microservicios reactivos

Uno de los objetivos principales de una arquitectura de microservicios es crear componentes independientes. Como resultado, será más fácil implementar, escalar y actualizar los servicios. Sin embargo, este objetivo no se logra por completo cuando se usa el patrón de orquestación, porque los microservicios individuales tienen dependencias directas de otros microservicios. Una forma de resolver esto es utilizar el patrón de coreografía, también conocido como microservicios "reactivos" o "impulsados ​​por eventos". En este patrón, los microservicios no se referencian directamente entre sí. En cambio, envían mensajes a los flujos de eventos a los que se han suscrito otros microservicios.

Vea el siguiente ejemplo:

En este ejemplo, digamos que el servicio de Cartera ha recibido instrucciones de agregar una posición de 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 se ha suscrito a ese flujo de eventos, por lo que recibe la notificación. Verifica para asegurarse de que el usuario tenga fondos suficientes en su cuenta. Si es así, reduce la cantidad de fondos en la cuenta de los usuarios y publica un evento en el flujo de eventos "Cuenta actualizada". Si el usuario no tiene fondos suficientes en su cuenta, entonces puede publicar un evento de error en un flujo de eventos diferente (no se muestra para simplificar el ejemplo). El microservicio de cartera está suscrito al flujo de eventos "Cuenta actualizada" y, cuando ve el evento publicado por el microservicio de cuentas, actualiza su cartera según la confirmación del servicio de cuentas.

La comunicación asincrónica en este tipo de arquitectura presenta el beneficio de que los servicios están altamente desacoplados entre sí: las instancias de cada servicio pueden ser reemplazadas, reasignadas o escaladas sin que los otros microservicios se preocupen por ellas. La compensación es que la naturaleza asincrónica 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 tipo de eventos que se produzcan, el sistema podría comportarse de forma inesperada. Esto se conoce como comportamiento emergente y es un desafío inherente en el desarrollo y prueba de microservicios coreografiados.

Patrón de llamadas de comando asincrónico

Hay diferentes patrones de mensajería asincrónica que se incluyen en la categoría más amplia de microservicios controlados por eventos. El patrón de llamadas de comando asincrónicas se usa cuando los microservicios necesitan ser orquestados usando acciones asincrónicas, donde un microservicio necesita llamar a otro microservicio de forma asincrónica, mientras se garantiza que el segundo microservicio recibió el mensaje. En este patrón, los mensajes se intercambian normalmente mediante colas.

Un marco común utilizado en arquitecturas de microservicio para implementar este patrón es RabbitMQ. Una encarnación específica de este patrón ocurre cuando un microservicio necesita publicar un evento para que lo procese un segundo microservicio y luego esperar a leer un evento de "respuesta" de ese segundo microservicio.

Considere el ejemplo de Portfolio que acabamos de discutir, en el que una llamada a la API REST le dice al microservicio Portfolio que agregue una posición. El servicio de cartera publica un evento en la cola de posición agregada para que el microservicio de cuentas lo procese y luego espera a que el servicio de cuentas publique un evento de respuesta en la cola de cuenta actualizada para que la llamada a la API REST pueda devolver los datos recibidos de ese evento. Hay dos formas diferentes de configurar un escenario de prueba para este ejemplo:

  1. El primer método consiste en crear un entorno con las colas necesarias, en el que se despliega el servicio Portfolio pero no el servicio Cuentas. Debido a que el servicio de Cuentas no está implementado, el escenario de prueba deberá simular el comportamiento del servicio de Cuentas publicando el evento esperado del servicio de Cuentas en el momento apropiado. Se construirá un escenario de prueba de Parasoft SOAtest con dos pruebas: una que ejecuta la API REST del servicio Portfolio y una segunda prueba que publica el evento desde el servicio Cuentas. Las pruebas deben configurarse para que se ejecuten al mismo tiempo, de modo que el evento del servicio de cuentas se publique mientras el servicio de cartera está escuchando el evento.
  2. En lugar de simular el servicio Cuentas mediante una prueba para publicar su evento, puede ser útil crear un servicio virtual reutilizable que escuche los eventos que se publican en la cola de Posición agregada y publique un evento resultante en la cola de Cuenta actualizada. Este microservicio virtual sería reutilizable en múltiples escenarios de prueba diferentes que podrían necesitarlo.

El primer enfoque es simple y crea un activo de prueba autónomo que no tiene dependencias externas adicionales en la infraestructura de prueba. El segundo enfoque es reutilizable y es una simulación más cercana del comportamiento real del sistema. Sin embargo, el segundo enfoque tiene el costo de construir, implementar y administrar un activo virtual separado.

Una variación del patrón de llamadas de comando asincrónicas es un microservicio que escucha en una cola un evento entrante, procesa el evento y luego publica un evento de seguimiento en una cola diferente para que uno o más microservicios lo procesen:

En este ejemplo, el microservicio Factura es el servicio que debe probarse. El servicio de pagos publica un evento en la cola de pago procesado de RabbitMQ para que el servicio de facturas lo recoja. El microservicio de facturas lee el evento de la cola, crea una factura y luego publica un evento en la cola de facturas creadas para indicar al microservicio de correo electrónico que envíe un correo electrónico al cliente con la factura. Para crear un escenario de prueba para el microservicio de Factura, se puede configurar un entorno de prueba que contenga dos colas RabbitMQ y el microservicio de Factura implementado. Se puede construir un escenario de prueba de Parasoft SOAtest que publique un evento de pago procesado en la cola de pago procesado. A continuación, el escenario se suscribe a la cola de factura creada para validar que el servicio de factura publique el evento de factura correspondiente. escenario de prueba muy simple que prueba muy bien el servicio Factura de forma aislada.

Patrón de manguera de incendios de eventos

El patrón de manguera de incendios de eventos se usa cuando diferentes fuentes producen un número muy alto de eventos que deben entregarse rápidamente a diferentes consumidores a través de un centro común. En este patrón, los mensajes se intercambian a través de temas (en contraste con el patrón de llamadas de comando asincrónicas donde los mensajes se intercambian a través de colas). Un marco común que se utiliza para implementar el patrón de manguera de incendios de eventos es el Apache Kafka framework, y se parece a esto:

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. Por ejemplo, algo como esto:

En este ejemplo, tenemos un microservicio de pronóstico que se suscribe a un tema de datos meteorológicos que recopila muchos datos meteorológicos diferentes de muchas fuentes diferentes. Luego procesa esos datos para actualizar su modelo de pronóstico y publica datos de pronóstico en el tema Datos de pronóstico. En este caso, debemos validar que el servicio de pronóstico publique los eventos esperados en el tema Datos de pronóstico para un conjunto específico de eventos de datos meteorológicos.

Esto se haría configurando un entorno de prueba que tenga los dos temas de Kafka y el servicio Forecast implementado. El escenario de prueba primero publicaría los eventos necesarios en el tema Datos meteorológicos y luego se suscribirá al tema Datos de pronóstico para verificar que el servicio de pronóstico haya publicado los eventos de datos de pronóstico correctos. Se necesitarían construir varios escenarios de prueba diferentes para verificar los diferentes tipos y el orden de eventos que se podría esperar que maneje el microservicio de Forecast.

Este es un escenario de prueba relativamente simple. El hecho de que el microservicio Forecast esté desacoplado de los otros microservicios tiene el afortunado efecto secundario de que la prueba del servicio Forecast también está desacoplada de los microservicios. En este caso, no necesita configurar un entorno complejo con servicios virtuales; simplemente puede crear escenarios de prueba que publiquen eventos y verificar que se creen los eventos correctos en respuesta.

Configuración de entornos de prueba

Muchos equipos de microservicios han adoptado un proceso de integración continua / implementación continua (CI / CD) para crear, probar e implementar microservicios en contenedores para automatizar el proceso y disminuir los riesgos asociados con la implementación de actualizaciones.

En este proceso, se crea automáticamente una imagen de contenedor que contiene el microservicio y se implementa en un entorno de prueba (a menudo administrado por Kubernetes o una distribución basada en Kubernetes como OpenShift), donde el microservicio puede validarse antes de pasar a pruebas de un extremo a otro y finalmente a la producción. Recomendaría leer CI / CD para microservicios en contenedores
 y Diseño de microservicios: integración continua. Ambos artículos describen muy bien este tipo de proceso.

Virtualización de servicios para probar microservicios

Algunos de los patrones de prueba que hemos discutido se basan en el uso de servicios virtuales para microservicios dependientes. Estos servicios virtuales deben estar altamente componentes y fácilmente implementables por las mismas razones que los microservicios que simulan son componentes. Para que la virtualización de servicios funcione en estos entornos, debe crear servicios virtuales en contenedores que se puedan implementar fácilmente.

Para crear un servicio virtual en contenedores, puede tomar una imagen base que contenga Parasoft Virtualize y todas sus dependencias, y colocarla en capas con otra imagen que contenga toda la configuración de activos virtuales para el servicio virtual. La nueva imagen para el servicio virtual se puede implementar como un contenedor en el entorno de Docker / Kubernetes junto con el contenedor para el microservicio bajo prueba y todas sus dependencias (virtualizadas).

Conclusión

A medida que los equipos adoptan microservicios, es importante comprender cómo probarlos suficientemente. Los patrones de mensajería y los patrones de prueba asociados que he discutido aquí 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.

A cree e implemente escenarios de prueba para sus microservicios con la máxima flexibilidad, puedes aprovechar Parasoft SOAtest, Parasoft Virtualize, y el Plataforma de prueba continua de Parasoft para garantizar la máxima calidad y fiabilidad de sus microservicios.

Cómo simplificar las pruebas de arquitecturas de microservicios
Escrito por

Nathan Jakubiak

Nathan es Director de Desarrollo de Parasoft. Él y sus equipos desarrollan capacidades de productos en las áreas de pruebas de UI (Selenic), pruebas de API (SOAtest), virtualización de servicios (Virtualize) y pruebas unitarias (Jtest). Ha estado con Parasoft desde 2000.

Reciba las últimas noticias y recursos sobre pruebas de software en su bandeja de entrada.

Prueba Parasoft