Pruebas API con SoapUI
5 de mayo de 2021
¿Qué vamos a ver?
En este artículo trataremos los aspectos básicos que nos permitan conocer y poder utilizar SoapUi como herramienta para automatizar las pruebas funcionales de nuestras APIs.
Veremos cómo instalarlo en nuestro equipo, conoceremos cuál es la estructura de un proyecto en SoapUI, los tipos de pruebas que podemos realizar (Steps, Cases, Suits), y por último, nos centraremos en los principales tipos de asertos que nos ofrece la herramienta.
¿Por qué es interesante?
SoapUI es una de las herramientas más conocidas a la hora de realizar pruebas automatizadas de nuestros servicios REST y SOAP.
Podríamos resumir sus principales ventajas de la siguiente manera:
- Es una herramienta open source (aunque también tiene su versión PRO de pago)
- Permite realizar pruebas funcionales
- Permite simular servicios (mocking)
- Facilita las pruebas de carga
- Incluye un complemento para realizar pruebas de seguridad
- Existe abundante documentación
- Permite establecer conexiones a bases datos mediante JDBC y JMS, entre otros
- Está en continua evolución
- Hay una comunidad muy activa
- Integración con sistemas como; maven, hudson, bamboo, junit, ANT, etc.
Cada proyecto de pruebas se puede exportar como fichero XML e incorporarlo a nuestro sistema de control de versiones.
SoapUI está desarrollado sobre la JVM por lo que permite el desarrollo de scripts en lenguaje Groovy y la integración de prácticamente cualquier librería java. Esta característica es muy importante puesto que aporta a la herramienta una gran potencia y versatilidad.
¿Dónde lo puedes usar?
Casos de uso habituales
Resulta interesante tener en cuenta la herramienta SoapUI cuando se trata de escenarios de pruebas de APIs que requieren de cierta complejidad en su preparación y validación.
Al tener la posibilidad de poder establecer conexiones con BBDD, y poder crear asertos por medio de scripts en Groovy, nos permite una mayor versatilidad en nuestras pruebas. Esto resulta especialmente útil es casos cómo:
- Complejidad en la preparación de datos necesarios para la prueba
- Inserciones en bases de datos
- Llamadas previas a otros endpoints
- Almacenar datos provenientes de otras llamadas
- Complejidad en la restauración el sistema después de la prueba
- Borrado de registros
- Programar validaciones/asertos complejos
- Validación compleja de datos (requieren cierta algoritmia/lógica)
- Uso de librerías externas (procesamiento de datos, envío de emails, etc.)
Dónde no es recomendable
Por el contrario, no sería una herramienta a utilizar cuando necesitamos desarrollar un set de pruebas rápidamente, deseamos realizar pruebas exploratorias o cuando simplemente necesitamos lanzar llamas a nuestra API para comprobar ciertas respuestas o resultados simples.
Para estos casos, resultaría más conveniente utilizar herramientas como Postman, Hoppcotch o Testmaze
¿Cómo funciona?
Entorno utilizado, prerrequisitos
Prerrequisitos:
- JRE 1.6+
- 1GB RAM
- 100MB de espacio en disco
Instalación - Cómo se instala SoapUI
En primer lugar accedemos a la web y descargamos el instalador. Una vez finalice la descarga hacemos doble clic, y el instalador se inicia inmediatamente. Solo debemos seguir los pasos indicados.
Ejemplos de casos de uso principales
En primer lugar tenemos que crearnos un nuevo proyecto REST sobre el cual luego añadiremos nuestros tests, para ello seguiremos los siguientes pasos:
Creación del proyecto
Abrimos el SoapUI y pulsamos sobre REST:
En la siguiente pantalla, donde introduciremos la URL de nuestro API, en nuestro caso utilizaremos https://reqres.in.
Esto nos genera la estructura de nuestro proyecto, la cual iremos completando paso a paso.
Estructura del proyecto
Antes de continuar debemos conocer cuál la estructura de un proyecto SoapUI:
- Workspace
- Project
- Service
- Resource
- Method
- Request
- Method
- Resource
- TestSuite
- TestCase
- TestSteps
- TestCase
- Service
- Project
Continuando con la creación de nuestro proyecto, podremos cambiar el nombre en la parte inferior de la pantalla en el apartado de “Project properties”
Una de las utilidades destacables en este apartado son las Custom Properties que en el caso de tener más de un entorno (desarrollo, preproducción, producción) nos aportan una solución fácil para el cambio entre ellos.
Para el uso de esta variable de entorno se define la siguiente variable: ${#Project#url_base_reqresAPI}
Para mantener las distintas propiedades del proyecto bastaría con guardar las propiedades en distintos archivos. Se realiza pulsando sobre el enlace que muestra la imagen a continuación:
Ahora, vamos a ir modificando la estructura básica que se nos ha generado automáticamente, y la completamos.
Vamos a editar nuestro “Resource”, para ello haremos “doble click” sobre él, y en la pantalla que se nos abre introducimos el path sobre el que vamos a trabajar. En nuestro caso, el path completo sería “https://reqres.in/api/users”, por lo que solo debemos añadir /api/users ya que el resto del path lo hemos definido en el nivel superior (Service)
Crear peticiones
El siguiente paso consistiría en comenzar a añadir los “Method”. Para nuestro ejemplo vamos a utilizar un GET y un POST, por ejemplo.
Como al crear el proyecto, inicialmente en la estructura se nos ha creado un “method” ya, lo reutilizamos y renombramos. Primero hacemos click con el botón derecho y escogemos “rename”, lo vamos a llamar ListUsers. A continuación hacemos doble click en la estructura sobre nuestro method y se abre una nueva ventana donde podremos indicar si es de tipo GET, POST, DELETE, PUT, HEAD, OPTIONS, TRACE ...
Una vez seleccionado el GET, le indicaremos los parámetros que necesitamos, en nuestro caso solo necesitaremos uno solo para indicar la página, y será de tipo QUERY. Para ello pulsaremos en el “+” de color verde, en el nombre pondremos “page”, y en value “2”, ya que vamos a pedir el listado de usuarios de la página 2.
Cuando ya tenemos definida la llamada a la API que se va a probar, el siguiente paso es comprobar que la respuesta es la que se espera. Para ello se crea el test propiamente dicho:
Existen distintos tipos de llamadas, una de las más utilizadas y que caracteriza a esta herramienta es la JDBC Request en la que introduciendo la configuración de la base de datos, se pueden realizar consultas sobre ésta para posteriormente compararlas con otras respuestas de tipo REST y comprobar si coinciden.
En nuestro caso, al carecer de la configuración de BBDD, realizaremos pruebas de la API. Para ello definiremos una REST Request con la que comprobaremos si la llamada antes definida devuelve la lista de usuarios correctamente
Tendremos que introducir los siguientes valores:
- Endpoint del API que estamos probando.
- El método o recurso de la API.
- Los parámetros de la request.
- Asertos.
Existe una sección del popup que muestra el resultado de la llamada al pulsar sobre el icono de ejecución: ▶️ (en la parte superior izquierda de la pantalla)
Añadir asertos
En el apartado de asertos es donde se realiza la verificación del correcto funcionamiento de la llamada. Para ello se introducirán tantas aserciones como se consideren necesarias.
Existen distintos tipos de comprobaciones según el origen de la propiedad que devuelve la llamada. En el caso que nos ocupa, al devolver un json, las aserciones a añadir pueden ser las siguientes:
- Contains
- JsonPath Count
- JsonPAth Existence Match
- JsonPath Match
- JsonPath RegEx Match
- Not Contains
- XPath Match
- XQuery Match
Pero también pueden tener como origen: Scripts, SLA, JMS, JDBC o información sobre la seguridad de la información.
La consulta más común en este tipo de llamadas es la del código de estado de la respuesta. En este caso al ser un método GET el que se comprueba, el código que verificamos es un 200.
Otro de los asertos que hemos añadido en nuestro proyecto de ejemplo es, JsonPath Match, nos sirve para localizar elementos dentro del Json que nos devuelve la petición, y poder comparar valores, ya sea con un valor fijo en el aserto o utilizando las properties.
En la siguiente imagen vemos lo que nos devuelve la petición, donde hay un array de elementos “data”, donde cada uno de ellos tiene:
- id
- first_name
- last_name
- avatar
Al crear nuestro aserto, en la parte superior, mediante $. seguido del path del campo indicaremos cual es el valor que queremos comparar. Y en la parte inferior pondremos el resultado esperado:
En caso de que el aserto falle, veremos que el test case se marca de color rojo, y al acceder a los asertos veremos cual a fallado y el motivo, como se ve en la siguiente imagen, donde hemos puesto el aserto que esperamos un 3, y en realidad el JSON devuelve un 1.
Otro ejemplo con este tipo de aserto sería el siguiente, donde lo que comparamos es el email.
Luego tendríamos otros tipo de aserto, el cual quizás sea el que más posibilidades nos ofrece; el Script Assertion, donde podremos escribir un trozo de código en groovy, para poder realizar comprobaciones más complejas.
En el ejemplo que hemos realizado, hemos obtenido la respuesta del JSON para poder parsearla y utilizarla en nuestro aserto.
Como mencionamos anteriormente podemos añadir una serie de properties a nuestro proyecto, a nuestros test case… En este caso hemos definido a nivel de test case una property “email” a la que hemos asignado un valor, el cual recuperamos.
<span style="font-weight: 400;">def</span><span style="font-weight: 400;">emailProperties</span><span style="font-weight: 400;"> = context.testCase.getPropertyValue(</span><span style="font-weight: 400;">"email"</span><span style="font-weight: 400;">)</span>
A continuación creamos un array donde almacenamos todos los email que encontramos en la respuesta del JSON.
Finalmente creamos nuestro aserto, donde comprobamos si el email definido en nuestra property se encuentra entre los retornamos por el servicio.
//imports import groovy.json.JsonSlurper //store the response in a variable def ResponseMessage = messageExchange.response.responseContent def response = new JsonSlurper().parseText(ResponseMessage) def i = 0 def infoResponse = response.data def userEmails = [] //obtain the value of a testCase property def emailProperties = context.testCase.getPropertyValue("email") //obtain the json emails while (infoResponse[i] != null){ userEmails[i] = infoResponse[i].email //log.info userEmails[i] i++;} //search for the required email until finding it in the response, if not Assert KO assert userEmails.contains(emailProperties)
Por último vamos a ver el aserto de tipo JsonPath Count, el cual podemos utilizar para contar las veces que aparece en la respuesta el elemento que le indiquemos. Como se muestra en la siguiente imagen, en la parte superior indicamos el path del elemento que queremos contar, y en la parte inferior indicamos el resultado esperado. Además en este ejemplo aprovechamos para indicar cómo se utiliza una property definida a nivel de test case.
El código de ejemplo puede encontrarse en este repositorio.
Conclusiones
Originalmente SoapUI surgió como herramienta para probar servicios, eso hace que se note que está más orientada al testing, y no simplemente a consumir una API de manera manual.
SoapUI es una aplicación muy potente que nos permite realizar pruebas de webservices (SOAP y REST). Con ella, seremos capaces de realizar tests más complejos y versátiles que con otras herramientas similares.
Uno de sus inconvenientes más destacables es su interfaz, ciertamente no se trata de una herramienta demasiado intuitiva y su diseño ha quedado algo desactualizado.
Otra desventaja importante es que no resulta del todo sencillo compartir proyectos de pruebas entre varias personas que estén realizando modificaciones de manera paralela. Aunque todo el proyecto queda exportando a un fichero XML, nuestra experiencia es que se generan bastantes conflictos al intentar realizar el “merge” entre versiones.
Finalmente si estás buscando una aplicación para realizar una suite de pruebas bien estructurada, para un proyecto con cierta complejidad a medio/largo plazo, SoapUI es tu herramienta, si por el contrario buscas algo más rápido, dinámico con una curva de aprendizaje menor, otras alternativas pueden resultar más interesantes.