BDD - desarrollo a través del comportamiento. BDD para microservicios es una colaboración del cliente, desarrolladores y probadores. BDD es un desarrollo que tiene en cuenta tanto los intereses técnicos como los requisitos comerciales. Este enfoque generalmente se usa para describir interfaces de aplicaciones, y dado que los microservicios son los detalles de la implementación del sistema, BDD también es adecuado para desarrollar microservicios. Cómo hacerlo: en la traducción de Ken Pugh.
Sobre el autor: Ken Pugh enseña a las empresas a desarrollar flexibilidad, crea sistemas de alta calidad utilizando el desarrollo impulsado por pruebas de aceptación, BDD, aceleración DevOps. Ken ha escrito varios libros sobre desarrollo de software, fue ganador del premio Jolt Award 2006 Prefactoring, uno de los creadores del curso SAFe Agile Software Engineering.
El comportamiento en BDD a menudo se expresa mediante la construcción Given / When / Then. Se nos da un cierto estado cuando ocurre una acción o evento, luego el estado cambia y / o se devuelve información.
Por ejemplo, la lógica sin estado, como las reglas comerciales y los cálculos, simplemente describe la conversión de entrada a salida.
Diseño orientado a interfaz utiliza el principio de
"diseño para interfaces, no implementaciones" . Los consumidores del servicio utilizan la interfaz que proporciona, no los elementos internos. Esto significa que dicha interfaz debe estar claramente pensada, incluido el comportamiento de error. Para la definición de términos en la descripción de la interfaz o su comportamiento, es posible utilizar DDD - Diseño controlado por dominio.
Los microservicios pueden ser sincrónicos cuando el consumidor
llama directamente a otro servicio y espera el resultado, o asíncrono cuando el
servicio responde a un mensaje que el cliente ha puesto en cola .
Considere un ejemplo de un servicio sincrónico.
Servicio sincrónico
Imagine un servicio que calcula un descuento en un pedido de ventas. Todo el proceso es un conjunto de operaciones relacionadas.

El comportamiento de este servicio se puede describir de la siguiente manera:
Get discount for a customer Given these inputs Customer category Order Amount Then service outputs Discount Amount
El servicio puede calcular el descuento usando algoritmos en el código, basados en la base de datos de datos local o contactando a otros servicios.
Puede usar JSON o XML como formato de mensaje. Sin embargo, describir el servicio sin especificar detalles de implementación ayuda a separar la semántica de las operaciones de la sintaxis.
¿Cuál es el comportamiento?
Con BDD, puede comenzar a diseñar con datos de muestra para tener una idea del comportamiento deseado. Los desarrolladores de servicios, clientes y probadores pueden encontrar este ejemplo. Las dos primeras columnas son la entrada al servicio, y la columna de la derecha es la salida.
El ejemplo muestra términos de dominio que pueden requerir un mayor refinamiento; por ejemplo, describa valores válidos.

Se entiende que el servicio devuelve el resultado correcto si los datos de entrada caen dentro del rango de valores aceptables.
La descripción del comportamiento, especialmente para microservicios, a menudo incluye respuestas en caso de fallas y errores. Una descripción de posibles fallas ayuda al consumidor a comprender qué hacer en tales casos. Los clientes del servicio pueden usar bibliotecas especiales, por ejemplo, Hystrix de Netflix, para corregir algunas de estas fallas.
Algunos posibles errores de nuestro servicio:
Las fallas pueden expresarse como constantes numéricas o de caracteres en el protocolo de comunicación.
El uso de nombres significativos en BDD ayuda a enfatizar la semántica de una falla, no su sintaxis.
Si el valor que se pasó como categoría no está en la lista de valores aceptables, el servicio devolverá un indicador de error: "Valor no válido de los parámetros de consulta". Esto se puede representar, por ejemplo, devolviendo el código HTTP 400 y la descripción de texto correspondiente.
Alternativamente, puede determinar el valor de descuento que se devolverá, por ejemplo, 0 si alguno de los parámetros es incorrecto. En este caso, el servicio debe ser responsable de registrar este problema para poder analizar sus consecuencias.
Las pruebas de BDD de servicio pueden formar un contexto para sus pruebas unitarias. En el proceso de diseño, la
responsabilidad de pasar las pruebas de BDD recae en clases y métodos . Las pruebas unitarias determinan estas responsabilidades.
Trozos
Al probar un servicio, a menudo se requieren trozos de servicios dependientes a los que llama. Son especialmente necesarios para servicios lentos, caros o aleatorios. Si el comportamiento del servicio de descuento nunca ha cambiado, cuando pruebe al cliente, puede usar la instancia de combate.
El cambio a menudo es inevitable, por lo que generalmente se necesitan trozos.

Un trozo siempre puede devolver los mismos valores, por ejemplo:
Las pruebas de los clientes pueden confiar en estos valores. En este ejemplo, el comportamiento constante puede ser suficiente. Para otras pruebas, es preferible una respuesta de código auxiliar personalizada.
Alternativamente, el recibo del servicio de descuento simplemente puede devolver la misma cantidad, independientemente de la entrada.
¿Cómo puede este trozo encajar en un escenario más amplio? Considere el comportamiento del sistema para un pedido, que incluye tanto un descuento como un impuesto. El impuesto es calculado por el microservicio, similar al descuento.

Hay un comprador
Descuento ajustable.
El impuesto está establecido.
Cuando un cliente realiza un pedido:
Luego ordene las opciones.
Servicios con estado
Si el servicio de descuento utiliza la base de datos para obtener información para calcular el descuento, entonces su contenido es el estado del servicio. Los cambios de estado en respuesta a las actualizaciones de datos deben documentarse. Supongamos que el servicio tuviera este estado.
En este caso, el servicio debería permitir cambiar estos datos. La actualización se puede organizar de modo que los elementos individuales se actualicen o toda la tabla se actualice inmediatamente. Aquí hay un ejemplo de una prueba de comportamiento para una actualización individual.
Dados los datos actuales.
Cuando se actualiza un artículo.
Luego datos actualizados.
También puede verificar que los datos actualizados se utilicen para calcular el descuento.
El servicio de descuento puede tener almacenamiento local para guardar datos en este ejemplo, pero también puede depender de un servicio de almacenamiento separado para estos datos. Si es así, las pruebas de la sección anterior se aplican a un servicio separado. Pero cada adicción agrega problemas. ¿Cuál debería ser el comportamiento de un servicio si sus dependencias no están disponibles? Para un servicio de descuento, ¿debería indicar esto una falla o debería simplemente devolver el valor predeterminado, el mismo 0? A veces puede usar políticas globales de manejo de errores, pero a
menudo la decisión depende del contexto del servicio .
Prueba de formulación y automatización
Una vez que el comportamiento del microservicio es consistente, se puede formular como pruebas automatizadas. Existen varios sistemas de prueba de microservicios, como PACT o Karate. Además, puede usar marcos BDD como Cucumber o FIT.
Por ejemplo, Cucumber usa bibliotecas para consultar servicios. Luego, se puede presentar información adicional sobre el entorno como parte del script.
Por ejemplo, un archivo de objeto Cucumber puede incluir.
Las opciones de paso dependen de sus convenciones de prueba.
Los valores en las dos primeras columnas se pueden transferir a cualquier convención de llamada, por ejemplo, para consultar parámetros. El resultado en cuerpo debe coincidir con la tercera columna. Si los nombres y valores de la consulta son los nombres y valores de las columnas, esto reduce las diferencias entre la prueba y la implementación.
Para su reutilización, se pueden escribir pasos para un servicio arbitrario que realiza cálculos o determina el resultado de una regla de negocios. En el ejemplo anterior, el uso del símbolo "?", Como en el "Monto de descuento" anterior, ayuda al analizador a distinguir entre entrada y salida.
Las pruebas también deben incluir fallas, por ejemplo.
Conclusión
Los microservicios dependen de otros servicios y sistemas, lo que requiere una especificación clara de las interfaces y sus pruebas precisas. Esto se puede lograr describiendo el comportamiento y las interfaces definidas por las pruebas. Con BDD, la funcionalidad de los servicios se describe mediante pruebas ejecutables que se centran
en la semántica de las operaciones, en lugar de la sintaxis . La automatización de tales pruebas generalmente requiere la configuración de talones de otros servicios, cuyo comportamiento se describe en sus pruebas individuales de BDD.
El diseño orientado a la interfaz - IOD, incluye obligaciones adicionales del servicio: restricción en el uso de recursos, ancho de banda e informes de errores. Juntos, BDD y IOD ayudan a describir el comportamiento del servicio para que los clientes puedan entenderlo fácilmente y confiar en él.
- BDD para microservicios se centra en la cooperación de la tríada: el desarrollador del servicio, el desarrollador del cliente y el probador.
- Cree convenciones claramente definidas para las interfaces de microservicios utilizando el IOD.
- Los microservicios generalmente requieren enchufes de prueba para acelerar las pruebas.
- Las pruebas deben ser independientes.
- Prueba de escenarios negativos en las pruebas.
Del 27 al 28 de mayo, durante el festival RIT ++ , en la conferencia QualityConf, Artyom Malyshev hablará sobre la importancia de expresar claramente el modelo de dominio en el código y mostrará cómo hacerlo usando ejemplos.
¡Ven a hablar sobre el desarrollo de productos de calidad y comparte tus ideas!