Testing de Carga de APIs con k6 y Aserciones Basadas en Umbrales
Como escribir y ejecutar tests de carga con k6 para medir rendimiento de APIs, validar SLOs e identificar cuellos de botella antes del despliegue a produccion
Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.
Testing de Carga de APIs con k6 y Aserciones Basadas en Umbrales
k6 es una herramienta moderna de testing de carga construida para desarrolladores. Usa JavaScript para scripting de tests y proporciona metricas integradas, aserciones de umbrales y escenarios modulares que te ayudan a validar requerimientos de rendimiento antes de que el codigo llegue a produccion.
Cuando Usar Esto
- Necesitas verificar que las APIs cumplen SLOs de tiempo de respuesta y throughput
- Quieres simular patrones de trafico de usuarios realistas
- El testing de regresion debe detectar degradacion de rendimiento en CI/CD
Requisitos Previos
- k6 instalado (
brew install k6o descargar desde k6.io) - Un endpoint de API ejecutandose para testear
Solucion
1. Script Basico de Test de Carga
// load-tests/basic.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 100 }, // Ramp up
{ duration: '5m', target: 100 }, // Estado estable
{ duration: '2m', target: 200 }, // Spike
{ duration: '5m', target: 200 }, // Carga sostenida
{ duration: '2m', target: 0 }, // Ramp down
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% bajo 500ms
http_req_failed: ['rate<0.01'], // Tasa de error bajo 1%
},
};
export default function () {
const response = http.get('https://api.example.com/products');
check(response, {
'status es 200': (r) => r.status === 200,
'tiempo de respuesta < 500ms': (r) => r.timings.duration < 500,
'tiene array de productos': (r) => r.json().length > 0,
});
sleep(1);
}
2. Testing de API Autenticada
// load-tests/authenticated.js
import http from 'k6/http';
import { check } from 'k6';
const BASE_URL = __ENV.BASE_URL || 'https://api.example.com';
const AUTH_TOKEN = __ENV.AUTH_TOKEN;
export const options = {
vus: 50,
duration: '10m',
};
export default function () {
const params = {
headers: {
Authorization: `Bearer ${AUTH_TOKEN}`,
'Content-Type': 'application/json',
},
};
// Simular un flujo de usuario
const cart = http.post(`${BASE_URL}/cart`, JSON.stringify({ items: [1, 2, 3] }), params);
check(cart, { 'carrito creado': (r) => r.status === 201 });
const checkout = http.post(`${BASE_URL}/checkout`, JSON.stringify({ cartId: cart.json('id') }), params);
check(checkout, {
'checkout exitoso': (r) => r.status === 200,
'orden confirmada': (r) => r.json('status') === 'confirmed',
});
}
3. Ejecutar Tests e Interpretar Resultados
# Ejecutar test de carga basico
k6 run load-tests/basic.js
# Ejecutar con variables de entorno
k6 run --env BASE_URL=https://staging.example.com --env AUTH_TOKEN=token123 load-tests/authenticated.js
# Output a InfluxDB para dashboards de Grafana
k6 run --out influxdb=http://localhost:8086/k6 load-tests/basic.js
# Ejecucion en cloud para carga distribuida
k6 cloud run load-tests/basic.js
4. Smoke Test para CI/CD
// load-tests/smoke.js
import http from 'k6/http';
import { check } from 'k6';
export const options = {
vus: 1,
iterations: 1,
thresholds: {
http_req_duration: ['max<2000'],
http_req_failed: ['rate===0'],
},
};
export default function () {
const endpoints = [
'/health',
'/products',
'/users/me',
];
for (const endpoint of endpoints) {
const res = http.get(`https://api.example.com${endpoint}`);
check(res, {
[`${endpoint} es 200`]: (r) => r.status === 200,
});
}
}
Como Funciona
- Virtual Users (VUs) simulan clientes concurrentes haciendo peticiones
- Stages definen patrones de ramp-up, carga sostenida y ramp-down
- Thresholds aseguran que metricas cumplan SLOs; thresholds fallidos salen con estado no-cero
- Checks validan correccion funcional bajo carga
Consideraciones de Produccion
- Ejecuta smoke tests en cada pull request para detectar regresiones basicas
- Programa soak tests (ejecuciones de horas) para encontrar memory leaks
- Usa ambientes separados para testing de carga; nunca testees produccion directamente
- Correlaciona metricas de k6 con herramientas APM (Datadog, New Relic) para analisis de root cause
Errores Comunes
- Testear desde una sola maquina que se convierte en cuello de botella
- No calentar la aplicacion antes de medir rendimiento de estado estable
- Usar
sleep()con intervalos aleatorios que no coinciden con think time de usuarios reales
FAQ
P: Cuantos VUs necesito para simular 10,000 usuarios reales? R: Depende de la frecuencia de peticiones. Si cada usuario hace una peticion cada 30 segundos, 50-100 VUs pueden simular 10,000 usuarios.
P: Puede k6 testear conexiones WebSocket?
R: Si, a traves del modulo experimental k6/ws, aunque herramientas dedicadas de WebSocket pueden ser mas apropiadas.
P: Como manejo datos dinamicos en tests de carga?
R: Usa papaparse para leer archivos CSV o genera datos randomizados con funciones random integradas.
Recursos Relacionados
Perform Load Testing on APIs
How to simulate realistic traffic, measure response times, and identify bottlenecks using k6 and JMeter for APIs and web services.
RecipeWrite Integration Tests
How to test multiple components working together using real databases, HTTP clients, and message queues in Python, JavaScript, and Java.
GuideSoftware Testing Strategy Guide
A practical guide to building a layered testing strategy with unit, integration, and end-to-end tests.