TL;DR

  • Locust = pruebas de carga basadas en Python (los tests son solo código Python)
  • Define comportamiento de usuario en locustfile.py con decoradores @task
  • Ejecuta con web UI (locust) o headless (locust --headless)
  • Modo distribuido: un master + N workers para escala masiva
  • Métricas en tiempo real: RPS, tiempos de respuesta, tasas de fallo

Ideal para: Equipos Python, pruebas de carga API, desarrolladores que prefieren código sobre GUI Omite si: Necesitas construcción de tests basada en GUI o extenso soporte de protocolos (usa JMeter) Tiempo de lectura: 12 minutos

Tu API maneja 100 requests por segundo en producción. Se acerca el Black Friday — ¿aguantará 10x? Necesitas saberlo antes que tus clientes lo descubran.

Locust te permite escribir pruebas de carga en Python. Sin configs XML, sin GUIs complejos. Solo código Python que simula comportamiento de usuarios.

¿Qué es Locust?

Locust es un framework open-source de pruebas de carga escrito en Python. Defines comportamiento de usuario como código Python, y Locust genera miles de usuarios concurrentes para estresar tu sistema.

Por qué Locust:

  • Python-native — los tests son código Python regular
  • Escalable — modo distribuido para millones de usuarios
  • UI en tiempo real — dashboard web muestra métricas en vivo
  • Ligero — bajo overhead de recursos por usuario
  • Flexible — testea cualquier sistema con librerías Python

Instalación

pip install locust

Verifica instalación:

locust --version

Tu primera prueba de carga

Locustfile básico

# locustfile.py
from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 3)  # Espera 1-3 segundos entre tareas

    @task
    def homepage(self):
        self.client.get("/")

    @task(3)  # 3x más probable que homepage
    def api_endpoint(self):
        self.client.get("/api/products")

Ejecutar el test

# Iniciar con web UI
locust -f locustfile.py --host=https://api.example.com

# Abre http://localhost:8089
# Configura usuarios y spawn rate
# Click Start

Modo Headless (CI/CD)

locust -f locustfile.py \
    --host=https://api.example.com \
    --users 100 \
    --spawn-rate 10 \
    --run-time 5m \
    --headless

Escribiendo escenarios de usuario

Múltiples tareas

from locust import HttpUser, task, between

class ApiUser(HttpUser):
    wait_time = between(0.5, 2)

    @task(5)
    def list_products(self):
        self.client.get("/api/products")

    @task(2)
    def get_product(self):
        self.client.get("/api/products/1")

    @task(1)
    def create_order(self):
        self.client.post("/api/orders", json={
            "product_id": 1,
            "quantity": 2
        })

Setup y Teardown

from locust import HttpUser, task, between

class AuthenticatedUser(HttpUser):
    wait_time = between(1, 3)

    def on_start(self):
        # Ejecuta una vez cuando el usuario inicia
        response = self.client.post("/api/login", json={
            "username": "test",
            "password": "password"
        })
        self.token = response.json()["token"]

    def on_stop(self):
        # Ejecuta una vez cuando el usuario termina
        self.client.post("/api/logout")

    @task
    def protected_endpoint(self):
        self.client.get("/api/profile", headers={
            "Authorization": f"Bearer {self.token}"
        })

Tareas secuenciales

from locust import HttpUser, task, between, SequentialTaskSet

class UserFlow(SequentialTaskSet):
    @task
    def browse(self):
        self.client.get("/products")

    @task
    def add_to_cart(self):
        self.client.post("/cart", json={"product_id": 1})

    @task
    def checkout(self):
        self.client.post("/checkout")

class EcommerceUser(HttpUser):
    tasks = [UserFlow]
    wait_time = between(1, 3)

Assertions y validación

from locust import HttpUser, task

class ValidatingUser(HttpUser):
    @task
    def check_api(self):
        with self.client.get("/api/status", catch_response=True) as response:
            if response.status_code != 200:
                response.failure(f"Got {response.status_code}")
            elif response.elapsed.total_seconds() > 2:
                response.failure("Too slow!")
            elif "ok" not in response.text:
                response.failure("Missing 'ok' in response")
            else:
                response.success()

Testing distribuido

Master Node

locust -f locustfile.py --master --host=https://api.example.com

Worker Nodes

# En cada máquina worker
locust -f locustfile.py --worker --master-host=192.168.1.100

Docker Compose

# docker-compose.yml
version: '3'
services:
  master:
    image: locustio/locust
    ports:
      - "8089:8089"
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile.py --master -H https://api.example.com

  worker:
    image: locustio/locust
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile.py --worker --master-host master
    deploy:
      replicas: 4

Entendiendo los resultados

Métricas clave

MétricaSignificado
RPSRequests por segundo (throughput)
MedianPercentil 50 de tiempo de respuesta
95%ile95% de requests más rápidos que esto
FailuresPorcentaje de requests fallidos
UsersCantidad actual de usuarios simulados

Exportar resultados

locust -f locustfile.py \
    --headless \
    --users 100 \
    --spawn-rate 10 \
    --run-time 5m \
    --csv=results \
    --html=report.html

Integración CI/CD

GitHub Actions

# .github/workflows/load-test.yml
name: Load Tests

on:
  schedule:
    - cron: '0 2 * * *'  # Diario a las 2 AM

jobs:
  load-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install Locust
        run: pip install locust

      - name: Run Load Test
        run: |
          locust -f locustfile.py \
            --host=${{ secrets.API_URL }} \
            --users 50 \
            --spawn-rate 5 \
            --run-time 2m \
            --headless \
            --csv=results

      - name: Upload Results
        uses: actions/upload-artifact@v4
        with:
          name: load-test-results
          path: results*.csv

Locust con Asistencia de IA

Las herramientas de IA pueden ayudar a escribir y optimizar tests de Locust.

Lo que la IA hace bien:

  • Generar escenarios de usuario desde specs de API
  • Crear variaciones de datos para carga realista
  • Sugerir umbrales de performance
  • Convertir tests de JMeter a Locust

Lo que necesita humanos:

  • Definir patrones realistas de comportamiento de usuario
  • Establecer niveles apropiados de carga
  • Interpretar resultados en contexto de negocio
  • Depurar problemas específicos de producción

FAQ

¿Qué es Locust?

Locust es un framework open-source de pruebas de carga basado en Python. Escribes comportamiento de usuario como código Python usando decoradores @task, y Locust genera usuarios concurrentes para generar carga. Provee una UI web para monitoreo en tiempo real y soporta testing distribuido para escala masiva.

¿Locust vs JMeter — cuál es mejor?

Locust usa código Python (mejor para desarrolladores que quieren control de versiones y soporte de IDE). JMeter usa GUI (más fácil para no-desarrolladores). Locust es más ligero y escala fácilmente con modo distribuido. JMeter tiene soporte de protocolos más amplio y más plugins. Elige Locust para equipos Python, JMeter para equipos que necesitan GUI o protocolos específicos.

¿Puede Locust testear WebSockets?

Sí, a través de clientes personalizados. La arquitectura de Locust soporta cualquier protocolo — implementas la lógica de conexión en Python. La comunidad provee librerías para WebSockets, gRPC y otros protocolos. Locust maneja la simulación de usuarios y métricas mientras tú controlas la implementación del protocolo.

¿Cuántos usuarios puede simular Locust?

Una sola máquina típicamente maneja 1,000-10,000 usuarios concurrentes dependiendo de la complejidad del escenario y recursos disponibles. Para tests más grandes, usa modo distribuido con un master coordinando múltiples workers. Esto escala a millones de usuarios a través de un cluster.

Recursos Oficiales

Ver También