Nodo Load Test
El nodo Load Test ejecuta pruebas de carga y rendimiento contra endpoints HTTP, simulando múltiples usuarios virtuales (VUs) en paralelo. Genera evidencias visuales en PNG con métricas detalladas y soporta criterios de aprobación automáticos mediante umbrales.
Visión General
| Propiedad | Valor |
|---|---|
| Tipo | load-test |
| Categoría | Performance |
| Color | 🟫 Ámbar (#92400E) |
| Entrada | in |
| Salida | out |
Tipos de Prueba
Cada tipo genera un perfil de carga diferente automáticamente a partir de los campos VUs y Duración.
| Tipo | Descripción | Cuándo Usar |
|---|---|---|
| Smoke | 1 VU, duración configurada | Validar que el endpoint responde antes de ejecutar pruebas mayores |
| Load | Ramp up → sostenimiento → ramp down | Verificar el comportamiento bajo carga normal esperada |
| Stress | Ramp agresivo hasta el límite | Identificar el punto donde el sistema comienza a degradarse |
| Spike | Pico súbito de VUs | Probar la reacción ante picos repentinos de tráfico (ej: Black Friday) |
| Soak | Carga sostenida por larga duración | Detectar memory leaks y degradación gradual |
| Breakpoint | Escalera progresiva de VUs | Encontrar el punto exacto de quiebre del sistema |
Configuración
Solicitud
| Campo | Tipo | Descripción |
|---|---|---|
| Credencial | string | Credencial HTTP guardada (rellena URL y auth automáticamente) |
| Método | string | GET, QUERY, POST, PUT, PATCH, DELETE, HEAD, OPTIONS |
| URL | string | Endpoint objetivo (soporta {{ }}) |
| Auth | string | Tipo de autenticación manual (si no usa credencial) |
| Headers | object | Cabeceras adicionales de la solicitud |
| Parámetros de Query | array | Pares clave-valor agregados a la URL |
| Tipo del Cuerpo | string | Ninguno, JSON, Texto bruto, x-www-form-urlencoded, multipart/form-data o Archivo binario |
| Body / Campos / Archivo | any | Contenido enviado según el tipo de cuerpo |
Cuerpo de la Solicitud
El constructor de solicitud del Load Test sigue el mismo modelo del nodo HTTP Request:
| Tipo | Cuándo usar |
|---|---|
| Ninguno | Solicitudes sin body |
| JSON | APIs REST que reciben objetos o arrays JSON |
| Texto bruto | XML, SOAP, payload textual o formato personalizado |
| x-www-form-urlencoded | Formularios URL encoded |
| multipart/form-data | Formularios con campos de texto y archivos |
| Archivo binario | Upload directo del contenido de un fileRef en el body |
Los campos de header y body aceptan expresiones {{ }}. Para enviar un archivo, use un fileRef que venga de otro nodo:
Archivo: {{ steps["file-generate"].outputs.fileRef }}
También es posible importar un comando curl; QANode intenta convertir método, URL, headers, query, body y campos de formulario al modo visual correspondiente.
Datos Dinámicos por Solicitud
La sección Datos dinámicos genera valores nuevos inmediatamente antes de cada solicitud de cada usuario virtual. Úsela cuando un endpoint exija un correo único, identificador externo, número secuencial, fecha futura u otro valor que no pueda repetirse durante la prueba.
Cree un valor en Datos dinámicos y utilícelo con:
{{ load.nombreDelValor }}
Los valores pueden utilizarse en:
- URL y parámetros de query;
- nombres y valores de headers;
- cuerpos JSON o de texto bruto;
- claves y valores de
x-www-form-urlencoded; - nombres y valores de campos de texto en
multipart/form-data.
El contenido de un archivo binario no se modifica. En solicitudes multipart, únicamente el nombre del campo y los campos de texto aceptan datos dinámicos.
Valores incorporados
Estos valores existen automáticamente y no es necesario crearlos:
| Expresión | Valor |
|---|---|
{{ load.runId }} | ID de la ejecución de QANode |
{{ load.requestId }} | Secuencia global de solicitudes, comenzando en 1 y única entre todos los VUs |
{{ load.vuId }} | Identificador del usuario virtual |
{{ load.iteration }} | Número de iteración dentro de ese VU |
{{ load.timestamp }} | Fecha y hora ISO generadas en el momento de la solicitud |
El mismo valor se reutiliza en todos los lugares de una única solicitud. En la siguiente solicitud, los valores generados se renuevan.
Ejemplo:
URL: https://api.ejemplo.com/orders/{{ load.requestId }}
Header X-Request-Id: {{ load.requestId }}
Body: { "requestId": "{{ load.requestId }}" }
URL, header y body reciben el mismo requestId en esa llamada.
Tipos disponibles
| Tipo | Configuración | Resultado |
|---|---|---|
| UUID | Solo nombre | UUID v4 nuevo por solicitud |
| Correo | Prefijo y dominio | Correo único con token de ejecución y requestId |
| Secuencia | Inicio e incremento | inicio + (requestId - 1) × incremento |
| Número aleatorio | Mínimo, máximo y decimales | Número aleatorio dentro del rango |
| Lista | Un valor por línea; selección aleatoria o secuencial | Un elemento de la lista por solicitud |
| Timestamp | Formato, desplazamiento y unidad | Fecha actual, pasada o futura |
| Template | Texto con otras expresiones load | Valor compuesto después de generar los demás datos dinámicos |
UUID
Nombre: externalId
Tipo: UUID
Uso: {{ load.externalId }}
Correo
Nombre: customerEmail
Tipo: Correo
Prefijo: performance
Dominio: example.com
Uso: {{ load.customerEmail }}
El resultado sigue este patrón y no se repite dentro de la ejecución:
performance_tokenDeEjecucion_142@example.com
Use un dominio reservado o controlado por la empresa. No use direcciones reales en una prueba que pueda enviar correos.
Secuencia
Nombre: customerNumber
Inicio: 1000
Incremento: 5
Las primeras solicitudes producen 1000, 1005, 1010 y así sucesivamente, independientemente del VU que las ejecute.
Número aleatorio
Nombre: amount
Mínimo: 10
Máximo: 100
Decimales: 2
Se admiten de 0 a 10 decimales. El máximo debe ser mayor o igual que el mínimo.
Lista
Nombre: region
Valores:
south
north
east
Selección: Secuencial
En modo Secuencial, los elementos se distribuyen en ciclos de acuerdo con requestId, lo que ayuda a equilibrar la carga. En modo Aleatorio, puede elegirse cualquier elemento en cada solicitud.
Timestamp
Formatos disponibles:
| Formato | Ejemplo |
|---|---|
| ISO | 2026-07-21T18:30:00.000Z |
| Unix | 1784658600 en segundos |
| Unix ms | 1784658600000 en milisegundos |
El desplazamiento admite segundos, minutos, horas o días. Use un valor positivo para el futuro y negativo para el pasado.
Nombre: expiresAt
Formato: ISO
Desplazamiento: 2
Unidad: Horas
Template
Los templates se procesan después de los demás datos dinámicos y pueden combinar sus valores:
Nombre: customerKey
Template: customer-{{ load.customerNumber }}-{{ load.externalId }}
Uso: {{ load.customerKey }}
Ejemplo completo — creación de usuario único
Cree estos valores:
| Nombre | Tipo | Configuración |
|---|---|---|
email | Correo | prefijo performance, dominio example.com |
externalId | UUID | — |
plan | Lista | basic, pro, selección secuencial |
sequence | Secuencia | inicio 1, incremento 1 |
Úselos en el body:
{
"email": "{{ load.email }}",
"externalId": "{{ load.externalId }}",
"plan": "{{ load.plan }}",
"sequence": "{{ load.sequence }}",
"requestId": "{{ load.requestId }}",
"createdAt": "{{ load.timestamp }}"
}
Cada llamada crea un payload diferente, incluso cuando varios VUs se ejecutan al mismo tiempo.
Reglas de los nombres
- deben comenzar con una letra;
- pueden contener letras, números,
_o$; - no pueden repetirse;
- no pueden usar los nombres reservados
runId,requestId,vuId,iterationotimestamp.
QANode valida las referencias desconocidas antes de iniciar la carga. Si el body usa {{ load.customer }} sin que exista una definición customer, la ejecución falla con un mensaje de configuración en lugar de enviar solicitudes incorrectas.
Buenas prácticas
- use una secuencia cuando necesite una distribución predecible;
- use una lista secuencial para equilibrar regiones, planes o categorías;
- use UUID o correo cuando la API exija unicidad;
- planifique la limpieza de los registros creados por la prueba;
- recuerde que los datos dinámicos cambian los inputs, pero no sustituyen los umbrales ni el análisis de métricas;
- ejecute un Smoke Test antes de la carga completa para validar el formato generado.
Configuración de Carga
| Campo | Tipo | Valor por defecto | Descripción |
|---|---|---|---|
| VUs | number | 10 | Número de usuarios virtuales simultáneos |
| Duración (s) | number | 30 | Duración total de la prueba en segundos |
| Think Time (ms) | number | 0 | Pausa entre solicitudes de cada VU |
| Timeout (ms) | number | 30000 | Tiempo máximo de espera por respuesta |
Para Smoke, el campo VUs está fijo en 1 y no se muestra.
Para Soak, la duración por defecto es 1800s (30 min).
Para Breakpoint, VUs representa el máximo de VUs que se alcanzarán.
Cómo funciona el Breakpoint
La prueba divide la duración total en pasos de ~30s, aumentando los VUs progresivamente:
VUs: 10 | Duración: 60s → 2 pasos de 30s
Paso 1: 0s → 30s → 5 VUs
Paso 2: 30s → 60s → 10 VUs
Stages Personalizadas
Active Custom en la sección Stages para definir manualmente el perfil de carga:
| Campo | Descripción |
|---|---|
| Duración (s) | Duración de esta stage en segundos |
| Target VUs | Número de VUs al final de esta stage |
Ejemplo de stages para una prueba de stress manual:
| Duración | Target VUs | Descripción |
|---|---|---|
| 30s | 10 | Ramp up inicial |
| 60s | 50 | Carga sostenida |
| 30s | 100 | Stress |
| 15s | 0 | Ramp down |
Autenticación
Usando Credenciales Guardadas
Seleccione una credencial de tipo HTTP/API. La URL base y los datos de autenticación se aplican automáticamente:
- Seleccione la credencial en el campo Credencial
- La URL base se completa automáticamente en el campo URL
- Complete con el path del endpoint:
/api/checkout
Autenticación Manual
| Tipo | Campos | Resultado |
|---|---|---|
| Bearer Token | Token | Header Authorization: Bearer {token} |
| Basic Auth | Usuario + Contraseña | Header Authorization: Basic {base64} |
| API Key | Header Name + Token | Header personalizado con el token |
Umbrales (Thresholds)
Los umbrales definen criterios de aprobación automáticos. Si algún umbral no se cumple, el nodo se marca como FALLIDO.
| Métrica | Descripción |
|---|---|
p50 | Percentil 50 de latencia (ms) |
p95 | Percentil 95 de latencia (ms) |
p99 | Percentil 99 de latencia (ms) |
avgDuration | Latencia promedio (ms) |
errorRate | Tasa de errores (%) |
rps | Solicitudes por segundo |
| Operador | Significado |
|---|---|
< | Menor que |
≤ | Menor o igual |
> | Mayor que |
≥ | Mayor o igual |
Ejemplos de umbrales comunes:
| Umbral | Significado |
|---|---|
p95 < 500 | 95% de las respuestas en menos de 500ms |
errorRate < 1 | Tasa de error menor al 1% |
rps > 10 | Mínimo 10 solicitudes por segundo |
p99 < 2000 | 99% de las respuestas en menos de 2s |
Sin umbrales configurados, el nodo siempre pasa (mientras el endpoint responda).
Outputs
| Output | Tipo | Descripción |
|---|---|---|
passed | boolean | true si todos los umbrales se cumplieron |
testType | string | Tipo de prueba ejecutada |
metrics | object | Métricas consolidadas de la prueba |
thresholds | array | Resultado de cada umbral configurado |
stages | array | Stages ejecutadas (auto o personalizadas) |
Estructura del objeto metrics
{
"totalRequests": 1141,
"errorCount": 0,
"errorRate": 0.0,
"rps": 34.49,
"avgDuration": 212,
"minDuration": 98,
"maxDuration": 668,
"p50": 182,
"p90": 332,
"p95": 451,
"p99": 579
}
Accediendo a los Outputs
// Verificar si pasó
{{ steps["load-test"].outputs.passed }} → true
// Total de solicitudes
{{ steps["load-test"].outputs.metrics.totalRequests }} → 1141
// Latencia p95
{{ steps["load-test"].outputs.metrics.p95 }} → 451
// Tasa de error
{{ steps["load-test"].outputs.metrics.errorRate }} → 0.0
// RPS
{{ steps["load-test"].outputs.metrics.rps }} → 34.49
Evidencias Generadas
El nodo genera automáticamente dos gráficos PNG como evidencia de la ejecución:
1. Reporte de Resumen (load-test-report.png)
Vista consolidada con:
- Tarjetas de métricas (p50, p95, p99, Avg, RPS, Requests, Errors, Error Rate)
- Gráfico de barras horizontales con distribución de latencia
- Gráfico de throughput a lo largo del tiempo (req/s)
- Pills de estado para cada umbral configurado
- Pie de página con las stages ejecutadas
2. Timeline RPS × Latencia (load-test-timeline.png)
Gráfico de doble eje con:
- Barras azules (eje izquierdo): RPS a lo largo del tiempo
- Línea naranja (eje derecho): Latencia promedio a lo largo del tiempo
- Línea morada discontinua (eje derecho): Latencia p95 a lo largo del tiempo
El gráfico de timeline es especialmente útil para pruebas Breakpoint y Stress, donde se puede visualizar exactamente en qué momento la latencia comienza a subir en respuesta al aumento de carga.
Ejemplos Prácticos
Smoke test — Validación básica
Tipo: Smoke
URL: https://api.ejemplo.com/health
Método: GET
Duración: 10s
Ideal para ejecutar al inicio de un flujo de pruebas — garantiza que el entorno está disponible.
Load test — Carga normal con umbrales
Tipo: Load
URL: https://api.ejemplo.com/products
Método: GET
VUs: 20
Duración: 60s
Umbrales:
- p95 < 500
- errorRate < 1
Stress test — Límites del sistema
Tipo: Stress
URL: https://api.ejemplo.com/checkout
Método: POST
VUs: 100
Duración: 120s
Body: { "productId": "123", "quantity": 1 }
Auth: Bearer → {{ variables.API_TOKEN }}
Umbrales:
- p99 < 2000
- errorRate < 5
Breakpoint — Punto de quiebre
Tipo: Breakpoint
URL: https://api.ejemplo.com/search
Método: GET
Max VUs: 200
Duración: 300s
Umbrales:
- p95 < 1000
- errorRate < 2
El sistema aumentará progresivamente de 1 a 200 VUs en pasos de ~30s. Cuando p95 supere 1000ms o los errores superen el 2%, el nodo marca como fallido — indicando el punto de quiebre.
Encadenando con otros nodos
[Load Test: Smoke]
│ outputs.passed = true
▼
[If: {{ steps.smoke.outputs.passed }}]
│ true → [Load Test: Carga completa]
│ false → [Log: "Smoke falló — entorno no disponible"]
Aislamiento de Cola
El nodo Load Test se ejecuta en una cola separada (qanode-load-tests) para no interferir con otros flujos en ejecución.
Para configurar un worker dedicado al Load Test:
WORKER_QUEUES=load-tests node dist/start.js
Para un worker que procese ambas colas:
WORKER_QUEUES=executions,load-tests node dist/start.js
Consejos
- Comience por Smoke antes de ejecutar pruebas de carga — garantiza que el endpoint responde correctamente
- Configure umbrales para que la prueba falle automáticamente cuando el sistema se degrade, sin necesidad de analizar los números manualmente
- Use el gráfico de timeline para identificar el momento exacto de degradación en pruebas Breakpoint y Stress
- Think Time simula comportamiento humano — útil para pruebas Soak donde se desea carga continua pero realista
- Las credenciales guardadas facilitan la ejecución en diferentes entornos (staging, producción) sin modificar el flujo
- Para pruebas confiables, hasta 100 VUs por instancia de worker. Por encima de eso, considere un worker dedicado
