Cuando tenemos muchos componentes ejecutándose en Microservice, a menudo encontramos problemas con Compatibilidad entre componentes que cambian con frecuencia Especialmente durante el comienzo del nuevo Proceso de Desarrollo, debe haber comunicación sobre la Interfaz o Especificación que cada componente utilizará para comunicarse bastante. Por supuesto, si alguien que ejecuta muchos proyectos de Microservicio como este, a menudo encontrará problemas con las Pruebas fallidas causadas por cambiar la interfaz o la Especificación de Microservicio. Algunos de ellos a menudo, ¿verdad?
Hoy me gustaría citar una de las Prácticas de Prueba (Automatización) que ayuda a Detectar los problemas causados por cada cambio de Microservicio. Práctica que llamaremos " Prueba de Contrato ".
Conocer pruebas de contrato
¿Alguna vez? La aplicación que queremos probar debe estar conectada a un servicio externo u otro componente que nuestro equipo no administra, a veces esos servicios pueden funcionar lentamente o cambiar, con No sabemos si la prueba que ejecutamos falla fácilmente. Con la aplicación, no tenemos que modificar el código de ninguna manera, lo que provoca que se produzca una prueba escamosa o una prueba no confiable.
Prueba de contrato con dobles de prueba
Una solución es usar Test Double o Pruebas doble . Test Doble es una herramienta que usamos para crear un Servicio Externo Mock o Stub que eliminamos nuestras dependencias no relacionadas con la prueba. Nuestra prueba es capaz de controlar el comportamiento y el resultado esperado que queremos. Creo que muchas personas pueden haber utilizado herramientas que pueden probar dobles, como Wiremock , NodeRed , Karate , etc.
Los dobles de prueba también tienen sus propias funciones, lo que permite que nuestra prueba se ejecute más rápido, lo que resulta en menos pruebas escamosas, pero la desventaja es que la baja fidelidad es una prueba que realmente no se ve como escenarios del mundo real.
Ese es el problema ¿Cómo sabemos que si un día ese Servicio Externo ha cambiado una nueva interfaz sin tener que comunicarse con nuestro equipo? Lo que puede hacer que nuestra aplicación no funcione correctamente cuando Deploy ya esté en producción (antes de darse cuenta de que es demasiado tarde)
Una forma de resolver este problema desde la fase de desarrollo fue crear un conjunto de casos de prueba por separado para la prueba del contrato para verificar que la interfaz utilizada en la conversación entre nuestra aplicación y el servicio externo sigue siendo la misma. cuando ejecuto el fallo de la prueba del contrato, entonces tenemos que pedir a la oficina para cuidar de él y mantener la externa Servicio de actualización, prueba, 'Dobles tenemos un realista y actual posible.
¿En qué se diferencia la Prueba de contrato de la Prueba de integración de API?
En resumen, la Prueba de contrato es una prueba para verificar la comunicación entre nuestra Aplicación y el Servicio externo para ver si sigue siendo la misma. La Prueba de contrato no verifica que los datos devueltos por el Servicio externo Cual es el valor Pero solo interesado en los datos devueltos ¿Existe una estructura o especificación que se haya acordado previamente? Que es diferente de la Prueba funcional API, que probará si los datos devueltos deben ser Los valores son correctos como se espera
Es posible que la ejecución de las pruebas de contrato no tenga que ejecutarse con mucha frecuencia, como la ejecución de la prueba de integración de API en general. Es posible que establezcamos el tiempo para que se ejecute como intervalo según corresponda, como Diario, Semanal, debería ser suficiente.
Prueba de contrato con Jest.JS
Hoy me gustaría recomendar una herramienta que lo ayudará a realizar pruebas de contrato muy bien en Node.js, que es Jest.JS (en otras plataformas de idiomas, hay bibliotecas que realizan pruebas de contrato bien, pero hoy yo ¿Puedo dar un ejemplo en Javascript?)
Jest.JS es un Marco de Pruebas Javascript de Código Abierto en Maintain by Facebook Jest es una Biblioteca de Pruebas muy poderosa en Node.js. Es ampliamente aceptada y es descargada por más de 10 millones de usuarios cada mes.
Jest también tiene una función que nos ayuda a realizar pruebas de contrato. Jest se llama prueba de instantáneas . La prueba de instantáneas ayudará a nuestro caso de prueba de instantánea y resultado esperado almacenado en un archivo para que podamos automatizarlo. Cuando ejecutamos la prueba la próxima vez, tomará los datos de la instantánea almacenados como resultado esperado en la ejecución actual sin tener que editar ningún código. Muy conveniente.
También podemos especificar el formato de nuestro archivo de instantáneas mediante el uso de Matchers proporcionados por Jest, como definir el patrón del objeto JSON de acuerdo con la estructura del esquema JSON que queremos, verificar los tipos de propiedad en varios objetos, etc. Que cumple con los requisitos de prueba de contrato que queremos muy bien
Comience a escribir pruebas de contrato.
Creé una API de servicio web RESTful como ejemplo de prueba de contrato en este artículo. Esta API es una API utilizada para obtener información de vuelo desde Bangkok (BKK) a Seúl (ICN), Corea del Sur, que lo haremos Supongamos que nuestro servicio externo es un servicio web que nos proporciona estos datos de vuelo.
sh $ curl -X GET https://api-flights.anezsoft.com/flights/routes/BKK/ICN
Flight API devuelve los datos para que sean un ejemplo como este
{"status": "success","data": [{"depart": "2019-02-28T01:00:00.000+07:00","arrive": "2019-02-28T08:40:00.000+09:00","flight": {"code": "7C","number": 2204},"airline": "Jeju Air","isDirectFlight": true,"flightStatus": "SCHEDULED","aircraft": {"manufacturer": "Boeing","model": "737-800"}},{"depart": "2019-02-25T01:05:00.000+07:00","arrive": "2019-02-25T08:25:00.000+09:00","flight": {"code": "LJ","number": 2},"airline": "Jin Air","isDirectFlight": true,"flightStatus": "SCHEDULED","aircraft": {"manufacturer": "Boeing","model": "737-800"}}]}
Ejemplo de cuerpo de respuesta JSON
Y esta es la interfaz de la API utilizada para comunicarse entre nuestra Aplicación y Servicio Externo. Por lo tanto, escribiremos las Pruebas de Contrato de acuerdo con esta Especificación.
Instalar dependencias
sh$ yarn add jest jest-extended axios
Creé un archivo de especificaciones de prueba de contrato como este.
import HttpStatus from 'http-status-codes'
import { FlightAPI } from '@/support/flight_api'
let flightAPI
describe('Flight API Contract Test', () => {
beforeAll(() => {
flightAPI = new FlightAPI()
})
test(`response should matched with snapshots`, async () => {
// when
const response = await flightAPI.getFlight('BKK', 'ICN')
// then
expect(response.status).toBe(HttpStatus.OK)
expect(response.data.status).toMatchSnapshot()
response.data.data.forEach((flightData) => {
expect(flightData).toMatchSnapshot({
aircraft: expect.objectContaining({
manufacturer: expect.toBeOneOf(['Boeing', 'Airbus']),
model: expect.any(String)
}),
airline: expect.any(String),
arrive: expect.stringMatching(/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}\+[0-9]{2}:[0-9]{2}/),
depart: expect.stringMatching(/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}\+[0-9]{2}:[0-9]{2}/),
flight: expect.objectContaining({
code: expect.any(String),
number: expect.any(Number)
}),
flightStatus: expect.toBeOneOf(['SCHEDULED', 'DELAYED', 'DIVERTED']),
isDirectFlight: expect.any(Boolean)
})
})
})
})
Ejemplo de contract.spec.js
Escribí el código para la API de llamadas usando Axios , el cliente HTTP Javascript más popular. Después de obtener la respuesta, datarealice un bucle en cada objeto de la matriz de la propiedad en el cuerpo de respuesta para hacer un cuerpo de respuesta de instantánea almacenado de esta manera.
expect(flightData).toMatchSnapshot()
Normalmente, si no pasamos ningún parámetro a la función toMatchSnapshot() Jest , veremos que es 100% de coincidencia exacta, es decir, debe ser exactamente igual en términos de la estructura de JSON y los valores de cada propiedad.Que en términos de pruebas de contrato, no necesitamos esa precisión. Solo queremos verificar la estructura del JSON y sus valores que cumplen con las especificaciones acordadas o no.
Por ejemplo, una propiedad de un tipo de Cadena de fecha, departy arrivepodemos verificar que el valor que se proporciona debe ser el patrón que queramos, o la Propiedad, flightStatusque puede tener solo los valores que acordamos, por ejemplo SCHEDULED|DELAYED|DIVERTED.
Qué Jest es amable al abrir el cuadro de Prueba de instantáneas para especificar el patrón de los Valores que queremos verificar Al establecer valores en la función toMatchSnapshot()utilizando Matchers proporcionados por Jest. Por ejemplo
exports[`Flight API Contract Test response should matched with snapshots 4`] = `
Object {
"aircraft": ObjectContaining {
"manufacturer": toBeOneOf<Boeing,Airbus>,
"model": Any<String>,
},
"airline": Any<String>,
"arrive": StringMatching /\\[0-9\\]\\{4\\}-\\[0-9\\]\\{2\\}-\\[0-9\\]\\{2\\}T\\[0-9\\]\\{2\\}:\\[0-9\\]\\{2\\}:\\[0-9\\]\\{2\\}\\.\\[0-9\\]\\{3\\}\\\\\\+\\[0-9\\]\\{2\\}:\\[0-9\\]\\{2\\}/,
"depart": StringMatching /\\[0-9\\]\\{4\\}-\\[0-9\\]\\{2\\}-\\[0-9\\]\\{2\\}T\\[0-9\\]\\{2\\}:\\[0-9\\]\\{2\\}:\\[0-9\\]\\{2\\}\\.\\[0-9\\]\\{3\\}\\\\\\+\\[0-9\\]\\{2\\}:\\[0-9\\]\\{2\\}/,
"flight": ObjectContaining {
"code": Any<String>,
"number": Any<Number>,
},
"flightStatus": toBeOneOf<SCHEDULED,DELAYED,DIVERTED>,
"isDirectFlight": Any<Boolean>,
}
`;
flight.contract.spec.js.snap
Trataré de ver si nuestras Pruebas de contrato realmente pueden detectar cambios al proporcionar flightStatusuna nueva Devolución de API que nunca haya sido asignada a los valores que conocemos antes, por ejemplo, DEPARTEDy luego ver si nuestra prueba fallará o no. Que?
Cuando se ejecutó, se encontró que la prueba falló . Debido a que Jest Detect descubrió que hay un Objeto que flightStatusno es uno de los estados que han sido Map. <SCHEDULED|DELAYED|DIVERTED>Eso muestra que Jest realmente puede ayudar a detectar cambios en las especificaciones de API que han cambiado para nosotros. Muy hermosa
Resumen
Se puede ver que podemos escribir pruebas de contrato fácilmente, lo que nos ayuda a detectar cambios que pueden ocurrir durante el desarrollo de muchos microservicios al mismo tiempo o para verificar la interfaz entre el servicio interno y el externo.
Espero que hayas encontrado este artículo útil para muchas personas. He creado todos los ejemplos de código del Proyecto GitHub. Puedes verlo en el siguiente enlace: ¡Feliz prueba!
Referencias
มารู้จักและสร้าง Contract Testing ด้วย Jest.JS กันเถอะ
código recomendado
https://github.com/nottyo/contract-testing-jestjs
Comentarios