Locust descreve usuários virtuais em Python e mede como um sistema reage à carga. Um bom cenário representa jornadas reais e tem objetivo definido, como encontrar o ponto em que a latência ultrapassa um limite, não apenas produzir o maior número possível de requisições.
Criar um locustfile
python -m pip install locust
from locust import HttpUser, between, task
class Leitor(HttpUser):
wait_time = between(1, 3)
@task(3)
def listar_posts(self) -> None:
self.client.get("/api/posts", name="GET /api/posts")
@task
def abrir_post(self) -> None:
self.client.get("/api/posts/python", name="GET /api/posts/:slug")
Pesos aproximam a frequência das ações, e wait_time evita um loop irreal sem pausas. Agrupar URLs dinâmicas com name mantém métricas úteis.
Executar com segurança
Comece com poucos usuários e aumente gradualmente. Em CI, o modo headless facilita limites reproduzíveis. Observe percentis de latência, taxa de falhas, throughput e recursos do servidor e também da máquina geradora.
Nunca aponte para produção sem autorização explícita, janela combinada, limites e botão de parada. Remova dados pessoais, use contas próprias para teste e valide o cenário funcionalmente antes da carga.
O artigo de segurança de APIs Python ajuda a revisar riscos, e o guia de métricas com Prometheus mostra observabilidade do servidor.
A documentação oficial do Locust, consultada em 22 de julho de 2026, cobre HttpUser, tarefas, execução headless e carga distribuída. Registre configuração, versão, dados e ambiente para que o resultado possa ser comparado depois.
Definir objetivo e perfil de carga
Comece com uma hipótese verificável: a busca deve sustentar 80 requisições por segundo durante dez minutos, com p95 abaixo de 400 ms e menos de 1% de erros. Isso define jornada, duração e aprovação. Diferencie carga, que verifica volume previsto; estresse, que procura o limite; e resistência, que mantém tráfego para revelar vazamentos ou filas crescentes. Registre commit, infraestrutura, massa de dados e configuração do gerador.
Modelar estado e dados
Jornadas reais exigem autenticação ou dados prévios. on_start prepara cada usuário virtual:
class Comprador(HttpUser):
wait_time = between(2, 5)
def on_start(self) -> None:
resposta = self.client.post(
"/api/login",
json={"email": "[email protected]", "senha": "segredo-de-teste"},
name="POST /api/login",
)
resposta.raise_for_status()
self.token = resposta.json()["token"]
@task
def consultar_carrinho(self) -> None:
self.client.get(
"/api/carrinho",
headers={"Authorization": f"Bearer {self.token}"},
name="GET /api/carrinho",
)
Use credenciais exclusivas de teste e forneça segredos por variável de ambiente. Não compartilhe uma conta entre milhares de usuários se sessões reais são independentes. Prepare identificadores suficientes e restaure o banco quando o cenário altera estado.
Validar sucesso funcional
Uma API pode responder 200 com corpo incompleto. catch_response classifica o resultado conforme o contrato:
@task
def buscar(self) -> None:
with self.client.get(
"/api/busca?q=python",
name="GET /api/busca",
catch_response=True,
) as resposta:
if resposta.status_code != 200:
resposta.failure(f"HTTP {resposta.status_code}")
elif "itens" not in resposta.json():
resposta.failure("resposta sem itens")
Mantenha a validação barata para o gerador não virar o gargalo. Regras detalhadas pertencem a testes funcionais; sob carga, verifique apenas o necessário para distinguir sucesso real.
Executar headless com rampa
locust -f locustfile.py \
--headless \
--host https://api.staging.example \
--users 100 \
--spawn-rate 5 \
--run-time 10m \
--csv resultados
--users significa usuários simultâneos, não requisições por segundo. A taxa depende também da espera e da latência. --spawn-rate controla a rampa, não o patamar. Faça antes um ensaio pequeno para conferir autenticação, agrupamento e limpeza. Em CI, aplique limites explícitos e preserve o CSV como evidência.
Interpretar percentis e gargalos
A mediana descreve a requisição central; p95 e p99 mostram a cauda lenta. Leia-os com throughput, falhas e números por endpoint. Correlacione o mesmo intervalo com CPU, memória, conexões, filas e banco. Se o throughput para de crescer enquanto a CPU do gerador satura, o limite pode estar no cliente.
Crie uma linha de base, mude uma variável e repita. Aquecimento de cache, autoscaling e coleta de lixo formam fases distintas. Um relatório confiável preserva a cronologia, não apenas um número favorável.
Distribuir e repetir
Locust coordena um mestre e vários workers quando uma máquina não basta. Todos devem executar a mesma versão e ter relógios sincronizados. Separe geradores da infraestrutura avaliada para não disputar recursos. Monitore sua CPU e confirme que DNS, balanceadores e limites de rede reproduzem o caminho desejado.
Antes do teste, documente autorização, destino, dados, limites e parada de emergência. Durante a execução, observe serviço e geradores. Depois, guarde configuração, commit, horários, CSV e incidentes. O resultado precisa levar a uma decisão: aceitar o limite, investigar um endpoint, ajustar capacidade ou repetir com outra hipótese. Ele fornece evidência sobre condições registradas, não garantia de ausência de falhas.
Evitar conclusões enganosas
Não misture endpoints rápidos e lentos em uma média. Analise cada operação e sua participação na jornada. Confirme se falhas de autenticação, limites de taxa ou cache reduziram artificialmente o trabalho do servidor. Milhares de respostas 401 rápidas não medem a capacidade da operação protegida.
Repita a execução para separar variação normal de regressão. Informe repetições, intervalo observado e mudanças entre elas. Se o ambiente compartilhado recebeu outro tráfego, registre a limitação. Transparência vale mais que falsa precisão.