Tutorials 20 April 2020

Pruebas de carga con Postman y k6

Mostafa Moradian, Developer Advocate

📖Lo que aprenderás

  • Cómo convertir una colección de postman en un script de K6
  • Cómo ejecutar el script creado por el conversor en K6

Introducción

En este artículo, queremos mostrar cómo utilizar una colección de Postman que he creado anteriormente para probar la carga de nuestra API de prueba. El proceso es bastante sencillo, como se muestra a continuación. Necesitas alimentar la colección de Postman exportada a nuestro convertidor postman-to-k6, y usar el script de K6 generado para cargar la prueba de tu propia API.

Guía de inicio rápido

# convertir la colección de postman a la prueba de K6
$ postman-to-k6 test-api.json \
-e env.json \
-o k6-script.js
# ejecutar la prueba de carga
$ k6 run \
--vus 100 \
--duration 5m \
k6-script.js

Guía en profundidad

Nuestra API de prueba y el escenario de pruebas

Para demostrar la potencia de K6 en diferentes escenarios, hemos creado nuestra API de prueba con varios endpoints de ejemplo, que está disponible en test-api.k6.io. Estos endpoints están disponibles en la colección de Postman:

Apis públicas

  • Listar todos los cocodrilos públicos
  • Obtener un solo cocodrilo público

Registro y autenticación

  • Registrar un nuevo usuario
  • Autenticación con token de portador/JWT

APIs privadas

  • Listar todos sus cocodrilos
  • Obtener un solo cocodrilo
  • Crear un nuevo cocodrilo (máximo 100)
  • Actualizar su cocodrilo
  • Actualizar los campos seleccionados de su cocodrilo
  • Eliminar su cocodrilo

El escenario consiste en probar todas las API públicas y privadas. Para las APIs privadas, se crea un usuario y se extrae su token. El token extraído se utiliza para hacer otras llamadas a la API. El orden es muy importante en las APIs privadas, ya que por ejemplo, no se puede eliminar un recurso inexistente. Por cierto, el cocodrilo es nuestra mascota.

Colección de Postman del API de prueba

Para facilitar las pruebas de nuestra API de pruebas y demostrar el uso de nuestro convertidor de Postman a K6, he creado una colección de Postman con casi todas las solicitudes de nuestra API de pruebas. En breve podrás ver cómo acceder a esta colección de Postman.

Test API Postman collection

Esta colección incluye un conjunto de variables de colección, variables de entorno, pre-scripts, pruebas, autorización con dos mecanismos diferentes, y usos del Postman Sandbox API.

Prueba de carga del API de prueba con la colección de Postman

Hemos creado una herramienta que convierte su colección de Postman en un script de K6, que se llama postman-to-k6. Puedes leer más sobre las características de esta herramienta en las release notes.

Para convertir la colección de Postman en un script de K6, debes seguir los siguientes pasos:

1. Opcional: Clonar el repositorio y saltar al paso 5:

He creado un repositorio para este artículo que contiene la colección de Postman exportada, junto con el script convertido y los archivos relacionados. Puedes clonar el repositorio e importar los archivos test-api.json y env.json a la aplicación Postman y posiblemente jugar con ellos si quieres.

Este repositorio contiene todo lo necesario para las pruebas de carga de nuestra API de prueba, por lo que puedes saltar al paso 4. Si utilizas tu propia colección, debes seguir todos los pasos para poder tener un script K6 fuera de tu colección de Postman, y poder ejecutar tu test de carga con él.

$ git clone https://github.com/grafana/k6-example-postman-collection.git

2. Instala Node.js (si no lo has hecho ya):

Para ello, te recomiendo encarecidamente que utilices algo como nvm, que es un gestor de versiones de Node.js que puedes utilizar para tener varias versiones de Node.js al mismo tiempo en tu máquina y poder cambiar a cualquiera de ellas rápidamente.

3. Instala la herramienta postman-to-k6:

La herramienta postman-to-k6 está desarrollada para ayudarte a convertir las peticiones dentro de tus colecciones Postman a scripts K6, que son en realidad código JavaScript.

$ npm install -g @apideck/postman-to-k6

4. Convierta su colección exportada de Postman en un script K6:

Asumiendo que tu colección exportada se llama test-api.json, puedes ejecutar este comando para convertirla en un script K6. El env.json incluye todas sus variables de entorno que se exportan desde Postman.

$ postman-to-k6 test-api.json -e env.json -o k6-script.js

Si necesitas un ajuste más fino de tu prueba (como hicimos nosotros arriba), como añadir datos o cambiar variables de entorno dentro de tu código, sólo tienes que echar un vistazo a la sección Opciones del README de postman a k6.

El script generado por el conversor debería ser como el siguiente. Como ves, he añadido manualmente la duración (de la ejecución de la prueba) para que sea de 1 minuto y también he añadido el recuento de usuarios virtuales (VU). Estas dos opciones permiten que el script se ejecute durante un minuto con 100 usuarios virtuales. Estos 100 VUs intentan hacer tantas peticiones como puedan para probar el servidor, lo que verás en la siguiente captura de pantalla.

1import "./libs/shim/core.js";
2import "./libs/shim/urijs.js";
3import URI from "./libs/urijs.js";
4import {
5 group
6} from "k6";
7
8export let options = {
9 maxRedirects: 4,
10 duration: "1m",
11 vus: 100
12};
13
14const Request = Symbol.for("request");
15postman[Symbol.for("initial")]({
16 options,
17 collection: {
18 BASE_URL: "https://test-api.k6.io/"
19 },
20 environment: {
21 USERNAME: "test@example.com",
22 PASSWORD: "superCroc2020",
23 FIRSTNAME: "John",
24 LASTNAME: "Doe",
25 EMAIL: "test@example.com",
26 ACCESS: null,
27 REFRESH: null,
28 CROCID: null
29 }
30});
31
32export default function () {
33 group("Public APIs", function () {
34 postman[Request]({
35 name: "List all public crocodiles",
36 id: "3ddd46c4-1618-4883-82ff-1b1e3a5f1091",
37 method: "GET",
38 address: "{{BASE_URL}}/public/crocodiles/"
39 });
40
41 postman[Request]({
42 name: "Get a single public crocodile",
43 id: "9625f17a-b739-4f91-af99-fba1d898953b",
44 method: "GET",
45 address: "{{BASE_URL}}/public/crocodiles/1/"
46 });
47 });
48
49 // NOTE: The rest of the requests can be accessed
50 // from the repository in step 1
51});

El script generado es un poco diferente de los scripts normales de K6, ya que incluye varias abstracciones para soportar diferentes funcionalidades de Postman, pero puedes mezclarlas con las peticiones http normal de K6. Además, hay un directorio libs al lado del script que incluye los shims y las librerías necesarias para que los scripts de Postman funcionen correctamente.

5. Instalar K6:

K6 soporta varias plataformas, incluyendo Windows, Linux, macOS y docker. Para instalarlo sólo tienes que seguir las instrucciones correspondientes a tu sistema.

NOTA: En cuanto a la instalación en Windows, también puedes utilizar el paquete choco k6.

6. Ejecuta K6 con el script generado:

Ahora que tienes tus colecciones convertidas en un script de K6, puedes invocar a K6 así:

$ k6 run k6-script.js

El resultado de la ejecución del script se muestra en la siguiente salida de consola:

/\ |‾‾| /‾‾/ /‾/
/\ / \ | |_/ / / /
/ \/ \ | | / ‾‾\
/ \ | |\ \ | (_) |
/ __________ \ |__| \__\ \___/ .io
execution: local
output: -
script: k6-script.js
duration: 1m0s, iterations: -
vus: 100, max: 100
done [==========================================================] 1m0s / 1m0s
█ Public APIs
█ Registration and authentication
█ Private APIs
data_received..............: 8.8 MB 146 kB/s
data_sent..................: 4.8 MB 80 kB/s
group_duration.............: avg=753.07ms min=239.15ms med=495ms max=4.06s p(90)=1.37s p(95)=1.73s
http_req_blocked...........: avg=12.31ms min=362ns med=1.52µs max=3.47s p(90)=1.83µs p(95)=1.96µs
http_req_connecting........: avg=1.95ms min=0s med=0s max=779.59ms p(90)=0s p(95)=0s
http_req_duration..........: avg=211.11ms min=104.42ms med=183.12ms max=924.43ms p(90)=304.25ms p(95)=404.24ms
http_req_receiving.........: avg=1ms min=41.14µs med=169.38µs max=130.94ms p(90)=328.31µs p(95)=2.22ms
http_req_sending...........: avg=205.91µs min=38.06µs med=163.76µs max=113.06ms p(90)=258.45µs p(95)=302.86µs
http_req_tls_handshaking...: avg=8.69ms min=0s med=0s max=2.43s p(90)=0s p(95)=0s
http_req_waiting...........: avg=209.9ms min=104.05ms med=182.22ms max=891.77ms p(90)=301.29ms p(95)=402.41ms
http_reqs..................: 26363 439.382653/s
iteration_duration.........: avg=2.28s min=1.43s med=2.01s max=6.55s p(90)=2.86s p(95)=3.64s
iterations.................: 2588 43.133267/s
vus........................: 100 min=100 max=100
vus_max....................: 100 min=100 max=100

Observaciones sobre el uso del conversor de postman a K6

1️. ¿Debemos basar nuestras pruebas de carga en el conversor Postman y en nuestras colecciones Postman?

Si estás usando el convertidor como una forma de onboarding, no. Si esperas convertir tu colección de forma continua y sin hacer muchas ediciones manuales después, sí.

Le recomendamos que utilice el conversor como una forma fácil de incorporar y luego reescribir sus scripts a código idiomático k6, ya que creemos que es más mantenible y menos probable que se degrade con el tiempo. Sin embargo, si conviertes desde colecciones postman de forma continua y ejecutas la salida de los scripts tal cual, podría tener sentido mantenerla tal cual.

2. ¿Está todo disponible en el script convertido?

No. Dado que k6 utiliza Goja para ejecutar JavaScript, y no es compatible con las APIs de los navegadores y de Node.js, hay algunas funcionalidades que faltan. Esto se puede arreglar mediante la importación de módulos de JavaScript incluidos. Para obtener una lista de bibliotecas compatibles, consulte jslib.k6.io.

3. ¿Qué ajustes has hecho en el script para que funcione?

En primer lugar, he eliminado el pre-script que contiene pm.sendRequest, porque no es compatible con el convertidor. Después, he sustituido la sintaxis jsonData.hasOwnProperty por la sintaxis k6 equivalente para extraer la información de la respuesta JSON: response.json("selector").

Test API Postman collection pre-script

API Postman vs. API k6

He aquí una rápida comparación de la API de Postman frente a la API de k6. Para ser justo, he incluido características de la aplicación GUI de Postman. En k6 tienes la opción de escribir el test en JavaScript. Postman también soporta javascript para hacer varias tareas, pero el enfoque es exponer las características a través de un conjunto más rico de elementos GUI.

FuncionalidadAPI de PostmanAPI de k6
Importando librerias externasLibrerias seleccionadasLibrerias seleccionadas más las incluidas
(APIs no relacionadas con el navegador ni con Node.js)
Hacer petición
Procesar respuesta
Parametrización
REST
GraphQL
Cookies
Proxy
SSL
OpenAPI/Swagger
(importar directamente)

(via generador de K6 en openapi-generator)
Checks
(assertions)

(Check API)
Grupos
(Colecciones)

(Grupo de APIs)
HTML parsing
(necesita librerias)

(internal HTML API)
Carga de archivo
Ciclo de vida de prueba
(solo con scripts)

(interno)

Como has visto anteriormente, hay muchas características soportadas por cada API, cada una en cierta medida. Algunas características necesitan bibliotecas externas, otras son internas. Ambas APIs son scriptables en JavaScript, y no todo es soportado por ambas, debido a las diferentes APIs del navegador y de Node.js utilizadas en las librerías.

Sin embargo, hay algunas características que sólo están disponibles en K6, lo que se debe en parte al hecho de que Postman está destinado a las pruebas de la API o a las pruebas funcionales de la API, pero k6 se centra más en las pruebas de carga de la API.

Pruebas funcionales vs. pruebas de carga

Las pruebas funcionales consisten en dar entrada al sistema (como caja negra) a través de una API y examinar los resultados, mientras que las pruebas de carga hacen básicamente lo mismo que las pruebas funcionales, pero con una carga adicional en la entrada al sistema.

Las pruebas funcionales proporcionan la entrada en cada punto final, y los resultados devueltos se verifican en términos de corrección contra un conjunto de especificaciones. Por su parte, las pruebas de carga proporcionan una gran cantidad de carga en cada punto final, y más bien tratan de agregar los metadatos devueltos por todas las respuestas.

Métricas de las pruebas de carga para medir el rendimiento

En lo que respecta a las mediciones, los metadatos incluirán el tiempo que tardó la solicitud en asentarse y la respuesta en regresar, que se miden mediante varias métricas. Por ejemplo, se puede medir la duración de la solicitud HTTP de todas las solicitudes y obtener su mínimo, máximo, promedio, mediana, percentil 90 y 95.

Pasar/fallar una prueba con thresholds (umbrales)

También tiene la opción de pasar/no pasar una prueba si alcanza/no alcanza ciertos umbrales. Por ejemplo, puede especificar que desea que el tiempo medio de respuesta sea inferior a 500 ms. Si la media está por debajo de eso, la prueba fallará, de forma muy parecida a las afirmaciones en las pruebas de software.

Filtrar los resultados con etiquetas

Ya que estás tratando con muchos resultados diferentes de diferentes endpoints, tu vida sería más fácil si pudieras filtrar los resultados. Las etiquetas (https://k6.io/docs/using-k6/tags-and-groups#tags) son soportadas por k6 para cumplir con este requisito.

Pruebas de carga de servidores WebSocket

En términos de implementación de protocolos, WebSocket es una de las características disponibles sólo en k6, en comparación con Postman, y puedes probar tu servidor WebSocket con él.

Conclusión

En este artículo he tratado de dar una rápida introducción a Postman, al convertidor postman-to-k6 y a nuestra herramienta de pruebas de carga K6. Todas estas herramientas combinadas pueden ayudarte a convertir tus peticiones de API en Postman en un script K6 para poder hacer pruebas de carga de tu API. Muchas de las características de Postman son soportadas por la herramienta postman-to-k6.

Nuestro objetivo final es agilizar el proceso de incorporación a nuestra herramienta de pruebas de carga, K6. Para ello, hemos creado muchas integraciones que pueden ayudarte a empezar a realizar pruebas de carga en tu infraestructura.

< Back to all posts