Módulo 13: Pruebas de Rendimiento con JMeter
Objetivos del módulo
- Comprender los tipos de pruebas de rendimiento
- Instalar y configurar Apache JMeter
- Crear Thread Groups, Samplers y Listeners
- Usar Assertions y Timers
- Analizar resultados (tiempos de respuesta, throughput)
- Ejecutar pruebas desde línea de comandos
1. Tipos de pruebas de rendimiento
| Tipo | Descripción | Objetivo |
|---|---|---|
| Load Testing | Carga esperada de usuarios | Verificar que cumple requisitos |
| Stress Testing | Carga superior al límite | Encontrar el punto de ruptura |
| Spike Testing | Picos repentinos de carga | Comportamiento ante subidas bruscas |
| Soak Testing | Carga sostenida durante horas | Detectar fugas de memoria |
| Scalability Testing | Incremento gradual de carga | Verificar escalabilidad |
graph LR
A[10 usuarios] -->|Load| B[100 usuarios]
B -->|Stress| C[500 usuarios]
C -->|Spike| D[1000 usuarios repentinos]
style A fill:#4CAF50,color:white
style B fill:#FF9800,color:white
style C fill:#f44336,color:white
style D fill:#9C27B0,color:white
Métricas clave
| Métrica | Descripción | Valor típico aceptable |
|---|---|---|
| Response Time | Tiempo de respuesta | < 2 segundos |
| Throughput | Peticiones/segundo | Depende del sistema |
| Error Rate | % de errores | < 1% |
| Percentil 90 (p90) | 90% de peticiones bajo este tiempo | < 3 segundos |
| Percentil 99 (p99) | 99% de peticiones bajo este tiempo | < 5 segundos |
2. Instalación de JMeter
Requisitos
- Java 8+ instalado
JAVA_HOMEconfigurado
Instalación
- Descarga desde jmeter.apache.org
- Descomprime en carpeta elegida
- Ejecuta
bin/jmeter.bat(Windows) obin/jmeter.sh(Mac/Linux)
Interfaz principal
┌────────────────────────────────────────────────────────────┐
│ File Edit Search Run Options │
├──────────────┬─────────────────────────────────────────────┤
│ Test Plan │ │
│ ├── Thread │ Panel de configuración │
│ │ Group │ del elemento seleccionado │
│ │ ├── HTTP │ │
│ │ │ Req │ │
│ │ ├── Timer│ │
│ │ ├── Assert│ │
│ │ └── Listen│ │
│ │ │
└──────────────┴─────────────────────────────────────────────┘
3. Conceptos fundamentales
Jerarquía de elementos
graph TD
TP[Test Plan] --> TG[Thread Group]
TG --> S[Sampler: HTTP Request]
TG --> T[Timer: Constant Timer]
TG --> A[Assertion: Response Assertion]
TG --> L[Listener: View Results Tree]
TG --> PP[Pre-Processor]
TG --> POP[Post-Processor]
TG --> CM[Config Element]
style TP fill:#2196F3,color:white
style TG fill:#FF9800,color:white
style S fill:#4CAF50,color:white
| Elemento | Función | Ejemplo |
|---|---|---|
| Test Plan | Contenedor raíz | Configuración global |
| Thread Group | Simula usuarios concurrentes | 100 usuarios, 10 seg ramp-up |
| Sampler | Genera la petición | HTTP Request, JDBC Request |
| Timer | Pausa entre peticiones | Constant Timer (1000ms) |
| Assertion | Valida la respuesta | Response Code = 200 |
| Listener | Visualiza resultados | View Results Tree, Summary Report |
| Config Element | Configuración compartida | HTTP Header Manager |
| Pre-Processor | Antes de la petición | JSR223 PreProcessor |
| Post-Processor | Después de la petición | JSON Extractor |
4. Thread Group (Grupo de Hilos)
El Thread Group define cuántos usuarios simulados ejecutarán los tests.
Configuración
| Parámetro | Descripción | Ejemplo |
|---|---|---|
| Number of Threads | Número de usuarios virtuales | 100 |
| Ramp-Up Period | Segundos para arrancar todos los hilos | 10 |
| Loop Count | Repeticiones por hilo | 5 |
| Duration | Tiempo máximo de ejecución | 60 seg |
📘 Concepto: Con 100 threads y ramp-up de 10 segundos, JMeter arranca 10 usuarios nuevos cada segundo.
Segundo 1: 10 usuarios activos
Segundo 2: 20 usuarios activos
...
Segundo 10: 100 usuarios activos
5. HTTP Request Sampler
Configuración de una petición GET
| Campo | Valor |
|---|---|
| Protocol | https |
| Server Name | api.example.com |
| Port | 443 |
| Method | GET |
| Path | /api/productos |
Petición POST con body JSON
| Campo | Valor |
|---|---|
| Method | POST |
| Path | /api/productos |
| Body Data | {"nombre": "Camiseta", "precio": 19.99} |
HTTP Header Manager
Añadir como hijo del Sampler o del Thread Group:
| Header | Valor |
|---|---|
Content-Type | application/json |
Authorization | Bearer ${token} |
Accept | application/json |
6. Assertions (Validaciones)
Response Assertion
| Verificar | Patrón |
|---|---|
| Response Code | 200 |
| Response Message | OK |
| Response Body | Contiene "nombre" |
| Response Headers | Contiene application/json |
JSON Assertion
| JSON Path | Valor esperado |
|---|---|
$.length() | > 0 |
$[0].nombre | Camiseta |
$.precio | 19.99 |
Duration Assertion
| Duración máxima | 2000 ms | |—————–|———|
⚠️ Importante: Si el tiempo de respuesta supera los 2000ms, la petición se marca como fallida.
7. Timers (Pausas)
| Timer | Descripción |
|---|---|
| Constant Timer | Pausa fija (ej: 1000ms) |
| Gaussian Random Timer | Pausa con distribución gaussiana |
| Uniform Random Timer | Pausa aleatoria en un rango |
| Constant Throughput Timer | Controla las peticiones/minuto |
Constant Throughput Timer
Si quieres exactamente 60 peticiones por minuto:
| Target Throughput | 60.0 | |—|—|
8. Listeners (Resultados)
Summary Report
| Métrica | Descripción |
|---|---|
| Samples | Nº total de peticiones |
| Average | Tiempo medio de respuesta (ms) |
| Min | Tiempo mínimo |
| Max | Tiempo máximo |
| Std. Dev. | Desviación estándar |
| Error % | Porcentaje de errores |
| Throughput | Peticiones por segundo |
| KB/sec | Datos transferidos por segundo |
View Results Tree
Muestra cada petición individual con:
- Request (petición enviada)
- Response Data (respuesta recibida)
- Response Headers
💡 Consejo: Desactiva View Results Tree en tests de carga reales. Consume mucha memoria.
Aggregate Report
Similar a Summary Report pero incluye percentiles (p90, p95, p99).
9. Variables y parametrización
Variables de usuario
Variables definidas en el Test Plan:
base_url = https://api.example.com
timeout = 5000
Uso: ${base_url}/api/productos
CSV Data Set Config
Archivo usuarios.csv:
usuario,password
user1,pass1
user2,pass2
user3,pass3
Configuración:
| Campo | Valor |
|---|---|
| Filename | usuarios.csv |
| Variable Names | usuario,password |
| Delimiter | , |
| Recycle on EOF | True |
Uso en el Sampler: ${usuario}, ${password}
10. Extractores (Post-Processors)
JSON Extractor
Extraer un valor de la respuesta JSON para usarlo en peticiones siguientes:
| Campo | Valor |
|---|---|
| Variable Name | token |
| JSON Path | $.access_token |
Ejemplo de flujo:
1. POST /api/login → Obtener token (JSON Extractor → ${token})
2. GET /api/perfil → Authorization: Bearer ${token}
3. GET /api/pedidos → Authorization: Bearer ${token}
Regular Expression Extractor
| Campo | Valor |
|---|---|
| Variable Name | sessionId |
| Regular Expression | JSESSIONID=(.+?); |
| Template | $1$ |
11. Controladores lógicos
| Controlador | Descripción |
|---|---|
| Transaction Controller | Agrupa peticiones como una transacción |
| If Controller | Ejecuta si se cumple condición |
| Loop Controller | Repite N veces |
| Random Controller | Ejecuta un hijo aleatorio |
| Once Only Controller | Solo se ejecuta en la primera iteración |
Transaction Controller
Thread Group
├── Transaction: Login
│ ├── GET /login (cargar página)
│ └── POST /login (enviar credenciales)
├── Transaction: Buscar Producto
│ ├── GET /productos
│ └── GET /productos?q=camiseta
└── Transaction: Checkout
├── POST /carrito
└── POST /pedido
12. Ejecución por línea de comandos (modo CLI)
# Ejecutar sin GUI (recomendado para pruebas reales)
jmeter -n -t test_plan.jmx -l resultados.jtl -e -o reporte_html/
# Parámetros:
# -n : Modo no-GUI
# -t : Archivo del test plan
# -l : Archivo de resultados
# -e : Generar reporte HTML al finalizar
# -o : Directorio del reporte HTML
Trabajo con propiedades
# Pasar parámetros al test
jmeter -n -t test.jmx -Jthreads=200 -Jrampup=20 -Jduration=120
En JMeter usar: ${__P(threads,100)} (100 es valor por defecto)
13. Ejemplo completo: Plan de rendimiento API REST
Test Plan: API Tienda Online
│
├── HTTP Header Manager
│ Content-Type: application/json
│
├── User Defined Variables
│ base_url = https://api.tienda.com
│
├── Thread Group: Carga Normal (100 usuarios, 30s ramp-up)
│ │
│ ├── Once Only Controller
│ │ └── POST ${base_url}/api/login
│ │ Body: {"username":"${usuario}","password":"${password}"}
│ │ JSON Extractor → ${token}
│ │
│ ├── HTTP Header Manager
│ │ Authorization: Bearer ${token}
│ │
│ ├── Transaction: Listar Productos
│ │ ├── GET ${base_url}/api/productos
│ │ │ Response Assertion: 200
│ │ │ Duration Assertion: < 2000ms
│ │ └── Constant Timer: 1000ms
│ │
│ ├── Transaction: Ver Producto
│ │ ├── GET ${base_url}/api/productos/1
│ │ │ JSON Assertion: $.nombre exists
│ │ └── Gaussian Timer: 500-1500ms
│ │
│ └── Transaction: Crear Pedido
│ ├── POST ${base_url}/api/pedidos
│ │ Body: {"productoId":1,"cantidad":2}
│ │ Response Assertion: 201
│ └── Constant Timer: 2000ms
│
├── CSV Data Set Config
│ File: usuarios.csv
│ Variables: usuario,password
│
├── Summary Report
├── Aggregate Report
└── View Results Tree (desactivar en carga real)
14. Ejercicios
Ejercicio 1
Crea un Thread Group con 50 usuarios (ramp-up 10s) que haga un GET a https://jsonplaceholder.typicode.com/posts. Añade un Response Assertion (200), un Duration Assertion (< 3000ms) y un Summary Report.
Ejercicio 2
Crea un flujo completo:
- GET
/posts→ Extraer el id del primer post - GET
/posts/${id}/comments→ Verificar que hay comentarios - Parametriza con CSV Data Set Config para probar con 5 ids diferentes.
Ejercicio 3
Ejecuta el test del Ejercicio 1 en modo CLI y genera un reporte HTML. Analiza: tiempo medio, p90, error rate y throughput.
Resumen
| Concepto | Descripción |
|---|---|
| Thread Group | Simula usuarios concurrentes |
| Sampler | Genera peticiones (HTTP, JDBC, etc.) |
| Assertion | Valida la respuesta |
| Timer | Controla el ritmo de peticiones |
| Listener | Visualiza y guarda resultados |
| CSV Data Set | Parametrización con datos externos |
| JSON Extractor | Extrae valores de respuestas JSON |
| Modo CLI | Ejecución real sin GUI (jmeter -n) |