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_HOME configurado

Instalación

  1. Descarga desde jmeter.apache.org
  2. Descomprime en carpeta elegida
  3. Ejecuta bin/jmeter.bat (Windows) o bin/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:

  1. GET /posts → Extraer el id del primer post
  2. GET /posts/${id}/comments → Verificar que hay comentarios
  3. 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)