En un artículo anterior, compartí mi experiencia de automatización en Robot Framework. Ahora hablaremos de un enfoque ligeramente diferente para probar la API para un proyecto en Kotlin.
Aprovechando la libertad de elegir la pila de tecnología y confiando en el deseo de probar algo nuevo "en la batalla", recurrí a Rest-Assured. No sin algunas dificultades, mis colegas y yo lanzamos pruebas y, como resultado del desarrollo del enfoque, lo registramos en la lista de tareas clave para este tipo de tarea.
(imagen utilizada como parodia)Todo comenzó con el hecho de que hubo una solicitud para automatizar las pruebas de API en uno de los nuevos proyectos en
el segmento de tecnología publicitaria . Hicimos Campaign Manager, DMP y varias integraciones con sistemas de terceros. Y los evaluadores tenían una tarea extremadamente simple: automatizar las pruebas de humo para una mayor integración en CI y un monitoreo constante del estado de esta API, ya que los sistemas de terceros están vinculados a ella y la operación correcta es crítica. La verificación de la lógica de negocios en este caso no era necesaria, ya que el servicio probado es esencialmente una interfaz proxy.
¿Por qué descansar asegurado?
Desde el punto de vista de la automatización de pruebas, logramos trabajar en una variedad de áreas: UI, web, móvil, escritorio, backend, REST API, SOAP.
El proyecto anterior nos dio mucha experiencia en Robot Framework, por lo que sería lógico usarlo. La mayoría del equipo de pruebas está familiarizado con él, y si se requiere un reemplazo urgente, esto se hará de forma rápida y prácticamente sin dolor. Pero se tomó una decisión diferente.
Primero, el proyecto en sí fue escrito en Kotlin y construido usando Gradle. Al mismo tiempo, en la etapa de diseño, se decidió que las pruebas automáticas no asignaran un proyecto separado. Como se señaló en los comentarios al artículo anterior, unir Java (Kotlin) y Robot Framework es un gran dolor, por lo que no tenía sentido referirse a RF. Además, al volver a trabajar con un robot, estaba interesado en probar un enfoque diferente. Además, en este proyecto podríamos elegir independientemente una pila de tecnología: el negocio no estableció sus propias condiciones.
En busca de ideas, recurrí a nuestro equipo de desarrollo, así como a colegas de las pruebas, y el CTO
me aconsejó mirar Rest-Assured (
rest-assured.io ). Después de leer la documentación y las pruebas de muestra en código abierto, el enfoque propuesto por Rest-Assured me pareció muy atractivo. Significa recibir una respuesta del backend en forma de JSON, que deserializamos en buenos viejos objetos Java.
Además, con esta estructura, puede trabajar como con un objeto normal. Como resultado, tenemos un enfoque orientado a objetos completamente normal para validar la correspondencia de la respuesta API a la estructura de objeto descrita. Como beneficio adicional, obtenemos una prueba rápida a prueba de fallas de la estructura de respuesta: si el objeto recibido al deserializar la respuesta API difiere en el número de campos o sus nombres, las pruebas caerán incluso antes de verificar los datos con un error de deserialización. Entonces entenderemos si necesitamos reparar el backend o actualizar las pruebas de acuerdo con los nuevos requisitos de API. En nuestro caso, esto fue importante porque, como mencioné anteriormente, muchos subsistemas de terceros están vinculados a la API.
Para mayor precisión, observo que se puede obtener aproximadamente la misma prueba a prueba de fallas en RF, pero de una manera ligeramente diferente. Sin embargo, la historia de hoy no se trata de eso. Personalmente, fue más conveniente y comprensible para mí ingresar desde el lado de Rest-Assured con una entidad que tiene ciertos campos y métodos.
Prueba de plumas
Antes de comenzar a usar la pila en un proyecto real, decidí probarlo en un pequeño servicio CRUD. Para no practicar inmediatamente sus propios errores, decidí buscar las mejores prácticas en esta pila y rápidamente encontré
un artículo de Philip Hauer , donde reflejaba su experiencia en automatización en Rest-Assured. Después de estudiar el artículo, escribir una versión funcional de las pruebas de mi servicio no fue difícil. Resultó simple, fácil de leer y entender.
A la batalla!
El proyecto comenzó, y cuando se describieron las primeras estructuras de respuesta, comenzó la preparación de la documentación de la prueba y la redacción de las pruebas automáticas. Para comprender el panorama general, les daré una pila completa de pruebas automáticas:
- Java
- JUnit4: ejecución y parametrización de scripts de prueba (anotación estándar @Parametrize),
- Rest-Assured: creación y ejecución de consultas,
- AssertJ - validación de los valores recibidos,
- Allure - edificio de informes,
- Gradle - montaje
- Jackson - deserialización.
Cuando se escribieron las primeras pruebas, el problema de la parametrización adecuada se hizo evidente. Transmitir valores simples de datos y el resultado esperado parecía extremadamente ineficiente y feo. No tuve tiempo de resolver este problema antes de las vacaciones, pero mis colegas, que estuvieron involucrados durante mi ausencia, lo resolvieron. Para una parametrización hermosa y fácil de leer, decidieron crear una clase base con las funciones de agregar, recibir y eliminar parámetros de objeto, de la cual se heredaron todas las clases cuyos objetos se usaron para llamar a los métodos API correspondientes.

Esto permitió literalmente sobre la marcha crear los datos necesarios y transmitirlos en los parámetros de prueba.

Rest-Assured le permite deserializar la respuesta a la clase requerida. La respuesta resultante se descompone en una estructura previamente conocida usando Jackson. Las clases para la deserialización se ven lo más simples posible: se describen todos los campos esperados con sus tipos.

Además, continúa el trabajo simple con objetos y la afirmación de campos específicos y sus valores.
Lo más difícil y no obvio que encontré en este enfoque es la incapacidad de pasar nulo a Rest-Assured como uno de los parámetros (el resultado es una caída en NullPointerException). Aparentemente, este es un problema conocido, pero el desarrollador no va a corregir la situación y recomienda enviar el campo vacío o no enviarlo. Ya enfrentamos este problema en la etapa en que la base del proyecto estaba lista y solo quedaba agregar clases de prueba. Por lo tanto, solo corregimos ligeramente nuestro código.
En general, me gustó el enfoque. Es curioso que después de algún tiempo comenzó a aplicarse en el proyecto de otro cliente (aunque no de nuestro suministro). Y colocamos la pila ensamblada para las API de pruebas de automatización (JUnit + AssertJ + Rest-Assured) en la categoría de claves para proyectos Java / Kotlin. En Python, extraerlo será contraintuitivo, ya que es mejor que las competencias de desarrollo y prueba se superpongan.
También vale la pena señalar que una de las ventajas de esta solución es su escalabilidad y adaptabilidad a la lógica compleja. Esto significa que es más adecuado para proyectos serios en los que realmente tiene sentido describir objetos grandes, código limpio y arquitectura de bloques, cuando hay piezas separadas responsables de preparar, transmitir y recibir datos en una forma legible, así como la verificación posterior de los datos para el cumplimiento algunas condiciones En proyectos pequeños, todo esto no tiene sentido.
Resumen
En aproximadamente un mes, pudimos automatizar unas 250 pruebas y proporcionar el nivel de cobertura requerido. Por supuesto, después del final del proceso de automatización, se realizó una presentación interna para todos, para que los empleados tuvieran una idea del trabajo realizado y pudieran aprender de la experiencia adquirida en este proyecto.
Autor del artículo: Dmitry Masters
PD: publicamos nuestros artículos en varios sitios de Runet. Suscríbase a nuestras páginas en
VK ,
FB o
Telegram-channel para conocer todas nuestras publicaciones y otras noticias de Maxilect.