Nó Load Test
O nó Load Test executa testes de carga e performance contra endpoints HTTP, simulando múltiplos usuários virtuais (VUs) em paralelo. Gera evidências visuais em PNG com métricas detalhadas e suporta critérios de aprovação automáticos via limiares.
Visão Geral
| Propriedade | Valor |
|---|---|
| Tipo | load-test |
| Categoria | Performance |
| Cor | 🟫 Âmbar (#92400E) |
| Entrada | in |
| Saída | out |
Tipos de Teste
Cada tipo de teste gera um perfil de carga diferente automaticamente a partir dos campos VUs e Duração.
| Tipo | Descrição | Quando Usar |
|---|---|---|
| Smoke | 1 VU, duração configurada | Validar que o endpoint responde antes de rodar testes maiores |
| Load | Ramp up → sustentação → ramp down | Verificar comportamento sob carga normal esperada |
| Stress | Ramp agressivo até o limite | Identificar o ponto onde o sistema começa a degradar |
| Spike | Pico súbito de VUs | Testar reação a picos repentinos de tráfego (ex: Black Friday) |
| Soak | Carga sustentada por longa duração | Detectar memory leaks e degradação gradual |
| Breakpoint | Escada progressiva de VUs | Encontrar o ponto exato de ruptura do sistema |
Configuração
Requisição
| Campo | Tipo | Descrição |
|---|---|---|
| Credencial | string | Credencial HTTP salva (preenche URL e auth automaticamente) |
| Método | string | GET, QUERY, POST, PUT, PATCH, DELETE, HEAD, OPTIONS |
| URL | string | Endpoint alvo (suporta {{ }}) |
| Auth | string | Tipo de autenticação manual (se não usar credencial) |
| Headers | object | Cabeçalhos adicionais da requisição |
| Parâmetros de Query | array | Pares chave-valor adicionados à URL |
| Tipo do Corpo | string | Nenhum, JSON, Texto bruto, x-www-form-urlencoded, multipart/form-data ou Arquivo binário |
| Body / Campos / Arquivo | any | Conteúdo enviado conforme o tipo do corpo |
Corpo da Requisição
O construtor de requisição do Load Test segue o mesmo modelo do nó HTTP Request:
| Tipo | Quando usar |
|---|---|
| Nenhum | Requisições sem body |
| JSON | APIs REST que recebem objetos ou arrays JSON |
| Texto bruto | XML, SOAP, payload textual ou formato customizado |
| x-www-form-urlencoded | Formulários URL encoded |
| multipart/form-data | Formulários com campos de texto e arquivos |
| Arquivo binário | Upload direto do conteúdo de um fileRef no body |
Campos de header e body aceitam expressões {{ }}. Para enviar arquivo, use um fileRef vindo de outro nó:
Arquivo: {{ steps["file-generate"].outputs.fileRef }}
Também é possível importar um comando curl; o QANode tenta converter método, URL, headers, query, body e campos de formulário para o modo visual correspondente.
Dados Dinâmicos por Requisição
A seção Dados dinâmicos gera valores novos imediatamente antes de cada requisição de cada usuário virtual. Ela é indicada para endpoints que exigem e-mail único, identificador externo, número sequencial, data futura ou outra informação que não pode ser repetida durante o teste.
Crie um valor na seção Dados dinâmicos e use-o com a sintaxe:
{{ load.nomeDoValor }}
Os valores podem ser usados em:
- URL e parâmetros de query;
- nomes e valores de headers;
- corpo JSON ou texto bruto;
- chaves e valores de
x-www-form-urlencoded; - nomes e valores de campos textuais
multipart/form-data.
O conteúdo de um arquivo binário não é modificado. Em multipart, somente o nome do campo e os campos de texto aceitam dados dinâmicos.
Valores nativos
Estes valores existem automaticamente e não precisam ser cadastrados:
| Expressão | Valor |
|---|---|
{{ load.runId }} | ID da execução do QANode |
{{ load.requestId }} | Sequência global da requisição, começando em 1 e sem repetição entre VUs |
{{ load.vuId }} | Identificador do usuário virtual |
{{ load.iteration }} | Número da iteração dentro daquele VU |
{{ load.timestamp }} | Data e hora ISO geradas no momento da requisição |
O mesmo valor é reutilizado em todos os lugares de uma única requisição. Na requisição seguinte, os valores gerados são renovados.
Exemplo:
URL: https://api.exemplo.com/orders/{{ load.requestId }}
Header X-Request-Id: {{ load.requestId }}
Body: { "requestId": "{{ load.requestId }}" }
URL, header e body receberão o mesmo requestId naquela chamada.
Tipos disponíveis
| Tipo | Configuração | Resultado |
|---|---|---|
| UUID | Apenas nome | UUID v4 novo por requisição |
| Prefixo e domínio | E-mail único com token da execução e requestId | |
| Sequência | Início e incremento | início + (requestId - 1) × incremento |
| Número aleatório | Mínimo, máximo e casas decimais | Número aleatório dentro do intervalo |
| Lista | Um valor por linha; seleção aleatória ou sequencial | Um item da lista por requisição |
| Timestamp | Formato, deslocamento e unidade | Data atual, passada ou futura |
| Template | Texto com outras expressões load | Valor composto depois que os demais são gerados |
UUID
Nome: externalId
Tipo: UUID
Uso: {{ load.externalId }}
Nome: customerEmail
Tipo: E-mail
Prefixo: performance
Domínio: example.com
Uso: {{ load.customerEmail }}
O resultado segue este padrão e não se repete dentro da execução:
performance_tokenDaExecucao_142@example.com
Use um domínio reservado ou controlado pela empresa. Não use endereços reais em um teste que possa disparar e-mails.
Sequência
Nome: customerNumber
Início: 1000
Incremento: 5
As primeiras requisições produzirão 1000, 1005, 1010 e assim por diante, independentemente de qual VU as executar.
Número aleatório
Nome: amount
Mínimo: 10
Máximo: 100
Casas decimais: 2
São aceitas de 0 a 10 casas decimais. O valor máximo deve ser maior ou igual ao mínimo.
Lista
Nome: region
Valores:
south
north
east
Seleção: Sequencial
No modo Sequencial, os itens são distribuídos em ciclos de acordo com o requestId, o que ajuda a equilibrar a carga. No modo Aleatório, qualquer item pode ser escolhido a cada requisição.
Timestamp
Formatos disponíveis:
| Formato | Exemplo |
|---|---|
| ISO | 2026-07-21T18:30:00.000Z |
| Unix | 1784658600 em segundos |
| Unix ms | 1784658600000 em milissegundos |
O deslocamento aceita segundos, minutos, horas ou dias. Use valor positivo para o futuro e negativo para o passado.
Nome: expiresAt
Formato: ISO
Deslocamento: 2
Unidade: Horas
Template
Templates são processados depois dos outros dados dinâmicos e podem combiná-los:
Nome: customerKey
Template: customer-{{ load.customerNumber }}-{{ load.externalId }}
Uso: {{ load.customerKey }}
Exemplo completo — criação de usuário único
Cadastre:
| Nome | Tipo | Configuração |
|---|---|---|
email | prefixo performance, domínio example.com | |
externalId | UUID | — |
plan | Lista | basic, pro, seleção sequencial |
sequence | Sequência | início 1, incremento 1 |
Use no body:
{
"email": "{{ load.email }}",
"externalId": "{{ load.externalId }}",
"plan": "{{ load.plan }}",
"sequence": "{{ load.sequence }}",
"requestId": "{{ load.requestId }}",
"createdAt": "{{ load.timestamp }}"
}
Cada chamada cria um payload diferente, inclusive quando vários VUs executam ao mesmo tempo.
Regras dos nomes
- devem começar com uma letra;
- podem conter letras, números,
_ou$; - não podem se repetir;
- não podem usar os nomes reservados
runId,requestId,vuId,iterationoutimestamp.
O QANode valida referências desconhecidas antes de iniciar a carga. Se o body usar {{ load.customer }} sem que customer exista, a execução falhará com uma mensagem de configuração em vez de gerar requisições incorretas.
Boas práticas
- use uma sequência quando precisar de distribuição previsível;
- use lista sequencial para equilibrar regiões, planos ou categorias;
- use UUID ou e-mail quando a API exigir unicidade;
- planeje a limpeza dos registros criados pelo teste;
- lembre que dados dinâmicos alteram os inputs, mas não substituem limiares e análise das métricas;
- faça um Smoke Test antes da carga completa para validar o formato gerado.
Configuração de Carga
| Campo | Tipo | Padrão | Descrição |
|---|---|---|---|
| VUs | number | 10 | Número de usuários virtuais simultâneos |
| Duração (s) | number | 30 | Duração total do teste em segundos |
| Think Time (ms) | number | 0 | Pausa entre requisições de cada VU |
| Timeout (ms) | number | 30000 | Tempo máximo de espera por resposta |
Para o tipo Smoke, o campo VUs é fixo em 1 e não é exibido. Para o tipo Soak, o padrão de duração é 1800s (30 min). Para o tipo Breakpoint, o campo VUs representa o máximo de VUs que serão atingidos.
Como o Breakpoint funciona
O teste divide a duração total em passos de ~30s, aumentando os VUs progressivamente:
VUs: 10 | Duração: 60s → 2 passos de 30s
Passo 1: 0s → 30s → 5 VUs
Passo 2: 30s → 60s → 10 VUs
Stages Customizadas
Ative Custom na seção Stages para definir manualmente o perfil de carga:
| Campo | Descrição |
|---|---|
| Duração (s) | Duração desta stage em segundos |
| Target VUs | Número de VUs ao final desta stage |
Exemplo de stages para um teste stress manual:
| Duração | Target VUs | Descrição |
|---|---|---|
| 30s | 10 | Ramp up inicial |
| 60s | 50 | Carga sustentada |
| 30s | 100 | Stress |
| 15s | 0 | Ramp down |
Autenticação
Usando Credenciais Salvas
Selecione uma credencial do tipo HTTP/API. A URL base e os dados de autenticação são aplicados automaticamente:
- Selecione a credencial no campo Credencial
- A URL base é preenchida automaticamente no campo URL
- Complete com o path do endpoint:
/api/checkout
Autenticação Manual
| Tipo | Campos | Resultado |
|---|---|---|
| Bearer Token | Token | Header Authorization: Bearer {token} |
| Basic Auth | Usuário + Senha | Header Authorization: Basic {base64} |
| API Key | Header Name + Token | Header customizado com o token |
Limiares (Thresholds)
Limiares definem critérios de aprovação automáticos. Se qualquer limiar não for atingido, o nó é marcado como FALHOU.
| Métrica | Descrição |
|---|---|
p50 | Percentil 50 de latência (ms) |
p95 | Percentil 95 de latência (ms) |
p99 | Percentil 99 de latência (ms) |
avgDuration | Latência média (ms) |
errorRate | Taxa de erros (%) |
rps | Requisições por segundo |
| Operador | Significado |
|---|---|
< | Menor que |
≤ | Menor ou igual |
> | Maior que |
≥ | Maior ou igual |
Exemplos de limiares comuns:
| Limiar | Significado |
|---|---|
p95 < 500 | 95% das respostas em menos de 500ms |
errorRate < 1 | Taxa de erro menor que 1% |
rps > 10 | Mínimo de 10 requisições por segundo |
p99 < 2000 | 99% das respostas em menos de 2s |
Sem limiares configurados, o nó sempre passa (desde que o endpoint responda).
Outputs
| Output | Tipo | Descrição |
|---|---|---|
passed | boolean | true se todos os limiares foram atingidos |
testType | string | Tipo de teste executado |
metrics | object | Métricas consolidadas do teste |
thresholds | array | Resultado de cada limiar configurado |
stages | array | Stages executadas (auto ou customizadas) |
Estrutura do objeto metrics
{
"totalRequests": 1141,
"errorCount": 0,
"errorRate": 0.0,
"rps": 34.49,
"avgDuration": 212,
"minDuration": 98,
"maxDuration": 668,
"p50": 182,
"p90": 332,
"p95": 451,
"p99": 579
}
Acessando os Outputs
// Verificar se passou
{{ steps["load-test"].outputs.passed }} → true
// Total de requisições
{{ steps["load-test"].outputs.metrics.totalRequests }} → 1141
// Latência p95
{{ steps["load-test"].outputs.metrics.p95 }} → 451
// Taxa de erro
{{ steps["load-test"].outputs.metrics.errorRate }} → 0.0
// RPS
{{ steps["load-test"].outputs.metrics.rps }} → 34.49
Evidências Geradas
O nó gera automaticamente dois gráficos PNG como evidência da execução:
1. Relatório de Resumo (load-test-report.png)
Visão consolidada com:
- Cards de métricas (p50, p95, p99, Avg, RPS, Requests, Errors, Error Rate)
- Gráfico de barras horizontais com distribuição de latência
- Gráfico de throughput ao longo do tempo (req/s)
- Pills de status de cada limiar configurado
- Rodapé com stages executadas
2. Timeline RPS × Latência (load-test-timeline.png)
Gráfico dual-axis com:
- Barras azuis (eixo esquerdo): RPS ao longo do tempo
- Linha laranja (eixo direito): Latência média ao longo do tempo
- Linha roxa tracejada (eixo direito): Latência p95 ao longo do tempo
O gráfico de timeline é especialmente útil para Breakpoint e Stress, onde é possível visualizar exatamente em que momento a latência começa a subir em resposta ao aumento de carga.
Exemplos Práticos
Smoke test — Validação básica
Tipo: Smoke
URL: https://api.exemplo.com/health
Método: GET
Duração: 10s
Ideal para rodar no início de um fluxo de testes — garante que o ambiente está no ar.
Load test — Carga normal com limiares
Tipo: Load
URL: https://api.exemplo.com/products
Método: GET
VUs: 20
Duração: 60s
Limiares:
- p95 < 500
- errorRate < 1
Stress test — Limites do sistema
Tipo: Stress
URL: https://api.exemplo.com/checkout
Método: POST
VUs: 100
Duração: 120s
Body: { "productId": "123", "quantity": 1 }
Auth: Bearer → {{ variables.API_TOKEN }}
Limiares:
- p99 < 2000
- errorRate < 5
Upload sob carga
Tipo: Load
URL: https://api.exemplo.com/upload
Método: POST
Tipo do Corpo: multipart/form-data
Campo arquivo:
file = {{ steps["file-generate"].outputs.fileRef }}
VUs: 10
Duração: 60s
Limiares:
- p95 < 1000
- errorRate < 1
Use esse padrão para validar endpoints que recebem anexos, documentos ou imagens.
Breakpoint — Ponto de ruptura
Tipo: Breakpoint
URL: https://api.exemplo.com/search
Método: GET
Max VUs: 200
Duração: 300s
Limiares:
- p95 < 1000
- errorRate < 2
O sistema irá aumentar progressivamente de 1 até 200 VUs em passos de ~30s. Quando p95 ultrapassar 1000ms ou erros superarem 2%, o nó marca como falha — indicando o ponto de ruptura.
Encadeando com outros nós
[Load Test: Smoke]
│ outputs.passed = true
▼
[If: {{ steps.smoke.outputs.passed }}]
│ true → [Load Test: Load completo]
│ false → [Log: "Smoke falhou — ambiente indisponível"]
Isolamento de Fila
O nó Load Test é executado em uma fila separada (qanode-load-tests) para não interferir nos outros fluxos em execução.
Para configurar um worker dedicado ao Load Test:
WORKER_QUEUES=load-tests node dist/start.js
Para um worker que processa ambas as filas:
WORKER_QUEUES=executions,load-tests node dist/start.js
Dicas
- Comece pelo Smoke antes de rodar testes de carga — garante que o endpoint está respondendo corretamente
- Configure limiares para que o teste falhe automaticamente quando o sistema degradar, sem precisar analisar os números manualmente
- Use o gráfico de timeline para identificar o momento exato de degradação em testes Breakpoint e Stress
- Think Time simula comportamento humano — útil para testes Soak onde você quer carga contínua mas realista
- Credenciais salvas facilitam a execução em diferentes ambientes (staging, produção) sem alterar o fluxo
- Para testes confiáveis, até 100 VUs por instância de worker. Acima disso, considere um worker dedicado
