En este post estaremos continuando lo tratado en el artículo anterior sobre la utilización de GraphWalker para modelar máquinas de estado, enfocando esta vez en API testing. Muchas gracias Charles y Diego de Abstracta por hacer toda la investigación y escribir el post.
La técnica de máquinas de estados se utiliza para modelar el comportamiento de un sistema bajo prueba, representando gráficamente los estados y las transiciones entre los mismos.
Como habíamos visto anteriormente, una de las grandes ventajas de GraphWalker es que nos permite recorrer un modelo mediante diferentes algoritmos, permitiendo así conseguir un mayor cubrimiento y definir fácilmente los caminos posibles para las pruebas. Esto es aplicable también cuando estamos haciendo API testing (endpoints REST o SOAP o una API a nivel de código).
Para demostrar lo mencionado, vamos a crear un proyecto de automatización de pruebas con la siguiente tecnología:
- Lenguaje Java.
- Entorno de desarrollo IntelliJ.
- Maven como gestor de dependencias.
- yEd para diagramar el modelo.
- GraphWalker para definir el camino que seguirán las pruebas a ejecutar.
Sistema de ejemplo
En este post utilizaremos un sistema de ejemplo bien simple para mostrar el uso de la herramienta. Dejamos fuera del scope de este artículo aspectos de modelado de máquinas de estado.
Dicha esta aclaración, estaremos automatizando una prueba para una API REST de Chuck Norris que permite realizar solicitudes simples HTTP y recibir los famosos Chuck Norris facts en formato JSON.
Si necesitás más sistemas de ejemplo, tanto web como API, podés consultar en este post.
Modelando
Siguiendo el hilo de testing basado en modelos, lo primero que tenemos que hacer es modelar el comportamiento que queremos probar de nuestro sistema bajo prueba. Para esto vamos a utilizar la herramienta yEd: un editor de grafos que nos permite guardar el modelo en formato graphml, siendo éste compatible con GraphWalker. También se podría utilizar GraphWalker Studio y guardar el modelo en formato JSON, pero según nuestras observaciones no cuenta con el mismo potencial que yEd, ya que no resulta tan práctica e intuitiva. En caso de querer cambiar el formato del modelo, por ejemplo, de graphml a JSON, puedes ver más información en este enlace.
Utilizando la herramienta “yEd” modelamos el sistema de ejemplo que utilizaremos en el post.
El modelo en el que nos basaremos, como se muestra en la imagen anterior, es un diagrama de flujo en función de la API chucknorris.io compuesto de 4 edges y 2 vértices (no es la representación de estados propiamente dicha, pero sirve para el ejemplo y muestra que este enfoque puede ser usado con los dos tipos de modelos: máquinas de estado y diagramas de flujo).
Al igual que está definido este modelo, es importante indicar siempre los edges con la preposición “e_” y los vértices con “v_” , ya que es la forma en que GraphWalker interpreta el modelo. No es dato menor, que para indicar el inicio de nuestro modelo se puede crear un vértice con el nombre Start, pero en caso de no realizar esto, se deberá indicar el “inicio” en nuestro test.
Los edges por lo general se representan para una acción a llevar a cabo y los vértices para validar un estado o verificar una respuesta.
Como vemos en los edges “ElegirCategoría” y “Aleatorio” tenemos una acción definida seguido de la barra inclinada “/”, que GraphWalker entiende como código Java. Además, nos permite agregar condicionales entre corchetes rectos “[…]” aplicando lógica a nuestro flujo en la máquina de estados, pero en este caso no se utilizará.
Generación de casos de prueba con GraphWalker
Una vez realizado el modelo en el editor, lo guardamos en formato graphml y lo validamos con GraphWalker CLI como se ve a continuación, donde“modelobajoprueba.graphml” es el nombre del archivo que queremos validar, “random(edge_coverage(100))” es el camino por el cual GraphWalker recorrerá el modelo en un 100% de las transiciones, basado en el algoritmo de Dijkstra y “offline” es el comando que indica a GraphWalker para generar el output con los casos de prueba.
java -jar graphwalker-cli-version.jar offline -m modelobajoprueba.graphml “random(edge_coverage(100))”
De esto, tendremos una salida similar a la siguiente:
En este caso, podemos identificar dos caminos que fueron recorridos en el modelo, el primero para “ElegirCategoria” y otro para cuando es “Aleatorio“. En caso de querer seguir otro tipo de algoritmo con un recorrido diferente al utilizado en el ejemplo (de recorrer todas las transiciones), puedes ver cómo utilizar los generadores aquí.
Continuando, procedemos a crear un proyecto en Java con la ayuda de Maven y generar la interfaz con los recursos necesarios para escribir nuestras pruebas. Para esto, debemos ejecutar el siguiente comando:
mvn archetype:generate -B -DarchetypeGroupId=org.graphwalker -DarchetypeArtifactId=graphwalker-maven-archetype -DgroupId=com.Graphwalker -DartifactId=carpetadelProyecto
En el parámetro “-DartifactId”, especificaremos el nombre de la carpeta del proyecto y en “DgroupId” indicaremos el nombre del subconjunto de carpetas deseado, conformando el package correspondiente a nuestros recursos.
Procederemos a guardar el modelo que habíamos generado anteriormente, en la ruta carpetadelproyecto/src/main/resources/carpeta/subcarpeta.
Una vez realizado lo anterior, estamos en condiciones de abrir nuestro proyecto en IntelliJ.
Nota: También es posible generar el Arquetipo directamente desde IntelliJ seleccionando Maven como Framework de nuestro proyecto.
Ahora que tenemos esto, vemos que se crearon dos clases por defecto; “Runner” y “SomeSmallTest”. El Runner es el encargado de realizar la ejecución y reporte de las pruebas llamando a la clase SomeSmallTest.
Para continuar con nuestro caso de prueba ejemplo, procedemos a editar la clase “SomeSmallTest“ y reemplazamos los métodos con los edges y vértices que allí se encuentran, por los que fueron definidos en nuestro modelo a la siguiente forma.
Como muestra la imagen en la línea 18, se le define a GraphWalker el algoritmo de Dijkstra para recorrer nuestro modelo.
Ejecución de pruebas sobre una API a partir de la máquina de estados
Lo que tenemos hasta ahora es un esqueleto de pruebas automatizadas que son capaces de recorrer los casos de prueba generados a partir del modelo y con la cobertura indicada. Lo que queremos hacer a continuación será invocar la API desde donde corresponda. Esto mismo podría hacerse invocando diversas herramientas, ya sea para ejecutar pruebas a nivel de web con Selenium, mobile con Appium, etc.
Para crear nuestros casos de prueba vamos a utilizar el cliente HttpComponents de Apache, que nos permite trabajar con nuestra API REST. Vale aclarar que también se podría utilizar cualquier otra herramienta o plugin como ser REST Assured. Para esto, incluiremos la siguiente dependencia en nuestro “pom.xml”.
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.12</version> </dependency>
Ya modificada la clase y actualizadas las dependencias, podemos crear nuestras pruebas de API. En este caso, crearemos una clase para manejar el cliente HTTP y así llamarlo dentro de cada método para la clase “SomeSmallTest”:
Luego que tenemos nuestro modelo con los scripts adaptados a las pruebas, ejecutamos el siguiente comando para generar los recursos que necesita GraphWalker para la interfaz de ejecución, en una carpeta que se creará automáticamente con el nombre target dentro del directorio src.
mvn graphwalker:generate-sources
Ejecutando los tests generados
Una vez que verificamos que se crearon las clases dentro del directorio, procedemos a la ejecución de los tests con el comando:
mvn graphwalker:test
Este comando ejecutará cada uno de los métodos conforme con el algoritmo que definimos en “SomeSmallTest” con un log similar a este:
Como vimos se recorrerá nuestro modelo ejecutando las requests con una cobertura del 100% de las transiciones del modelo, mostrando el siguiente resultado:
Ejecutando directamente sobre el modelo
Por último, GraphWalker ofrece un Player con la posibilidad de mostrar la ejecución en tiempo real sobre el modelo, visibilizando el algoritmo gráficamente en un navegador. Para esta ejecución, es necesario cumplir con los pasos que se encuentran en la documentación. Primero descargando el archivo index.html y luego creando una nueva clase con las definiciones del Servidor del WebSocket que se encuentran comentados en el archivo mencionado, al que se deberá indicar el puerto de ejecución que en su defecto está en 8887.
Logrado lo anterior, inicializamos el WebSocket e ingresamos la siguiente dirección en una instancia de nuestro navegador:
file://<RUTA DEL ARCHIVO>index.html?wsURI=<IP DE LA MÁQUINA QUE CORRE LOS TESTS>:<PUERTO DEFINIDO EN EL WEBSOCKET>
Al ejecutar el WebSocket podremos observar la recorrida de GraphWalker sobre nuestro modelo de la siguiente forma:
Conclusiones
Esta prueba de concepto demuestra la posibilidad de hacer API testing con GraphWalker y cambiar la forma tradicional de crear tests automatizados, logrando llevar nuestras pruebas a otro nivel, aplicando técnicas de generación de casos de pruebas basados en máquinas de estado. Podemos integrarlo con múltiples herramientas, como por ejemplo Junit, Selenium o TestNG, entre otras; y además disponer de los beneficios que nos brinda Java, así como también generar nuestros sets de prueba automáticamente para un modelo y algoritmo dado.
GraphWalker posee varias utilidades para definir escenarios, adoptando el testing basado en modelos como su estandarte, y así brindando la posibilidad de avanzar a la creación de tests automatizados variando los caminos según las necesidades.
Integrando GraphWalker a nuestro proyecto de automatización de pruebas obtenemos muchas ventajas, ya sea en la creación de los casos y su cubrimiento, en la ejecución y organización de los tests, o también en la visualización de los mismos y cómo se relacionan. Este último factor puede ser de gran valor si tenemos un proyecto que se presenta con un inventario de pruebas extenso, o incluso oficiando de plataforma para mostrar nuestro trabajo de una forma más amigable y gráfica.
Aquí te compartimos el repositorio del proyecto del ejemplo realizado para el post para que vos lo puedas reproducir.
En el repo de GraphWalker encontrarás proyectos de ejemplo para seguir investigando y probando.