O que significa “performance inicial” e por que testar cedo
Em testes de API, “performance inicial” é o conjunto de verificações simples e repetíveis que você executa desde o começo para detectar regressões de tempo, tamanho de resposta e comportamento sob pressão leve. A ideia não é fazer um teste de estresse completo, e sim estabelecer limites práticos (orçamentos) por endpoint e validar confiabilidade: responder dentro de um tempo aceitável, de forma estável, e degradar de maneira previsível quando necessário.
Métricas essenciais para critérios iniciais
1) Tempo de resposta por endpoint (latência)
Defina um limite por endpoint com base no tipo de operação. Por exemplo: leitura simples tende a ser mais rápida que agregações complexas. Em testes, meça o tempo total do request (do envio até o último byte da resposta) e compare com um limite (SLA interno de teste).
- Exemplo de critério: GET /users/{id} deve responder em até 300 ms em ambiente de teste estável.
- Separação útil: limite “ideal” (para alertar) e limite “máximo” (para falhar o build).
2) Variação: p95 e p99 (conceito)
Médias escondem picos. Percentis ajudam a entender a cauda de latência:
- p95: 95% das requisições foram mais rápidas (ou iguais) a esse valor; 5% foram mais lentas.
- p99: 99% foram mais rápidas; 1% foram mais lentas (cauda mais crítica).
Para verificações iniciais, você pode coletar 50–200 amostras e calcular p95/p99 de forma simples. O objetivo é detectar variação anormal (ex.: p95 subiu muito mesmo que a média pareça ok).
3) Tamanho de payload (request/response)
Payload grande aumenta latência, custo de rede e risco de timeouts. Em testes, valide:
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
- Tamanho máximo de resposta para endpoints de listagem (ex.: não ultrapassar 200 KB por página).
- Tamanho máximo de request para endpoints de criação/atualização (ex.: rejeitar acima de 1 MB com erro apropriado).
Na prática, você mede o tamanho do corpo (bytes) e, quando possível, valida também o cabeçalho Content-Length (se presente) como indicador.
4) Limites de paginação
Paginação é um ponto comum de regressão de performance. Mesmo sem reexplicar paginação, em performance você quer garantir que:
- Existe um limite máximo de itens por página (ex.:
limitmáximo 100). - Pedidos acima do limite são normalizados (reduzidos para o máximo) ou rejeitados com erro consistente.
- O tempo de resposta não cresce de forma descontrolada quando o cliente pede o máximo permitido.
Passo a passo: definindo “orçamentos” de performance por endpoint
Passo 1 — Escolha endpoints críticos e cenários representativos
Selecione um conjunto pequeno (5–15) que represente o uso real:
- 1–3 endpoints de leitura frequente (ex.: detalhes, listagem curta).
- 1–2 endpoints de escrita (ex.: criar pedido).
- 1 endpoint “pesado” (ex.: relatório, agregação) para acompanhar tendência.
Passo 2 — Defina limites iniciais (latência, payload e paginação)
Crie uma tabela de critérios. Exemplo:
| Endpoint | Cenário | Limite (p95) | Limite (p99) | Payload máx. | Paginação |
|---|---|---|---|---|---|
| GET /users/{id} | Usuário existente | 300 ms | 600 ms | 30 KB | N/A |
| GET /orders | limit=50 | 600 ms | 1200 ms | 200 KB | limit máx=100 |
| POST /orders | Pedido simples | 800 ms | 1500 ms | 50 KB req | N/A |
Esses números são exemplos; o importante é que sejam explícitos, versionados e revisados quando o produto muda.
Passo 3 — Padronize o ambiente e reduza ruído
Para que o teste seja repetível:
- Use dados de teste estáveis (mesmos registros, mesma cardinalidade).
- Evite rodar junto com jobs pesados no mesmo ambiente.
- Fixe a região/rota de rede quando possível.
- Execute um “aquecimento” (warm-up) com algumas requisições antes de medir.
Passo 4 — Colete amostras e calcule p95/p99
Faça N requisições (ex.: 100) e registre tempos. Um cálculo simples de percentil pode ser feito ordenando os tempos e pegando o índice correspondente.
# Exemplo conceitual (pseudocódigo) para p95/p99 a partir de tempos em ms: tempos = [ ... ] ordenar(tempos) p95_index = ceil(0.95 * len(tempos)) - 1 p99_index = ceil(0.99 * len(tempos)) - 1 p95 = tempos[p95_index] p99 = tempos[p99_index]Se o volume de amostras for pequeno, trate p99 com cautela (ele fica muito sensível). Ainda assim, é útil para detectar “picos” recorrentes.
Smoke de performance e testes de carga leves
Smoke de performance (rápido, em pipeline)
Objetivo: detectar regressões óbvias em minutos. Características:
- Baixa concorrência (1–5 usuários virtuais).
- Poucas iterações (ex.: 20–50 por endpoint).
- Critérios simples: p95 abaixo do limite, taxa de erro ~0, payload dentro do máximo.
Exemplo de checklist de smoke:
- p95 e p99 dentro do orçamento definido.
- Nenhum timeout do cliente.
- Sem aumento inesperado de payload (ex.: resposta duplicada, campos extras gigantes).
- Paginação respeita limite máximo e não degrada além do esperado.
Teste de carga leve (pré-produção ou nightly)
Objetivo: validar comportamento sob pressão moderada sem virar teste de estresse. Características:
- Concorrência moderada (ex.: 10–50 usuários virtuais, dependendo do sistema).
- Duração maior (ex.: 10–30 minutos) para observar estabilidade.
- Métricas: p95/p99, throughput, taxa de erro, e variação ao longo do tempo.
Mesmo em carga leve, o foco é confiabilidade: manter latência e erros estáveis, sem degradação progressiva (ex.: vazamento de recursos, filas crescendo).
Timeouts: critérios e como testar
Definindo timeouts do cliente de teste
Timeout é um limite do lado do cliente para evitar que testes fiquem pendurados. Defina pelo menos:
- Connection timeout: tempo máximo para estabelecer conexão.
- Read/response timeout: tempo máximo esperando resposta.
- Total timeout: limite global por request (quando a ferramenta suporta).
Critério prático: o timeout do teste deve ser maior que o limite de performance esperado, mas não tão alto a ponto de mascarar travamentos. Exemplo: se o p99 esperado é 1200 ms, um timeout total de 3000–5000 ms pode ser razoável para capturar travas reais sem gerar falsos positivos por variação pequena.
Passo a passo — teste de timeout
- Configure o cliente com um timeout total (ex.: 3 s).
- Chame um endpoint que pode demorar (ou simule latência via ambiente de teste).
- Valide que, ao exceder o timeout, o teste falha com erro claro (do cliente) e registra métricas.
- Garanta que o sistema não fica em estado inconsistente (ex.: uma escrita que “talvez” completou). Para operações de escrita, prefira validar via consulta posterior (quando aplicável) e/ou usar identificadores idempotentes quando existirem.
Comportamento em degradação: 429/503 e backoff
429 Too Many Requests (limitação de taxa)
Quando a API aplica rate limit, o cliente pode receber 429. Em testes de confiabilidade, você valida:
- O status 429 aparece quando esperado sob pressão.
- Existe sinalização de quando tentar novamente (ex.:
Retry-After), se a API adota isso. - O sistema não retorna 500 em vez de 429 (limitação deve ser controlada).
503 Service Unavailable (indisponibilidade temporária)
503 indica degradação/indisponibilidade temporária. Em testes, verifique:
- Se a API retorna 503 em cenários de sobrecarga em vez de “travar” até timeout.
- Se a resposta é consistente e rápida (falhar rápido pode ser melhor do que consumir recursos).
- Se existe orientação para retry (quando aplicável).
Backoff e retry: como validar sem mascarar problemas
Backoff é a estratégia de esperar antes de tentar novamente, geralmente com aumento progressivo (exponencial) e um fator aleatório (jitter) para evitar “ondas” de retry.
Em testes de API, você pode validar backoff do ponto de vista do cliente de teste (ou SDK) com um cenário controlado:
- Provoque 429/503 (ex.: aumentando concorrência ou usando um ambiente com limitação configurada).
- Verifique que o cliente respeita
Retry-Afterquando presente. - Verifique que o número máximo de tentativas é limitado (ex.: 3 retries) e que há um tempo total máximo para não prender o fluxo.
# Exemplo de política (conceitual): max_retries = 3 base_delay_ms = 200 backoff = base_delay_ms * (2 ^ attempt) + jitter(0..100) respeitar Retry-After se existir e for maior que backoffImportante: em smoke de performance, normalmente você desliga retry automático para não esconder regressões. Em testes específicos de resiliência, você liga retry para validar o comportamento esperado.
Validando estabilidade (repetibilidade) das medições
O que é estabilidade em testes de performance de API
Estabilidade significa que, repetindo o mesmo teste em condições semelhantes, os resultados ficam dentro de uma faixa aceitável. Não é “sempre igual”, mas não deve oscilar de forma imprevisível.
Como testar repetibilidade na prática
- Execute o mesmo cenário 3–5 vezes (em sequência ou em horários próximos).
- Compare p95/p99 entre execuções.
- Defina um critério de variação aceitável (ex.: p95 não pode variar mais que 20% entre execuções, salvo mudanças conhecidas).
Se a variação for alta, investigue ruído (ambiente instável, cache frio/quente, concorrência externa) antes de concluir que houve regressão.
Detecção de regressão: baseline e tendência
Além de comparar com um limite fixo, mantenha um baseline histórico (últimas execuções) e observe tendência. Um endpoint que “piora” 5% por semana pode ainda estar abaixo do limite, mas indica risco.
Respostas parciais e assíncronas: interpretando 202 Accepted
Quando 202 aparece e o que significa para testes
202 Accepted indica que a requisição foi aceita para processamento, mas não foi concluída no momento. Em termos de performance, isso muda o que você mede:
- Latência do 202: tempo para aceitar e enfileirar (deve ser baixo e estável).
- Tempo de conclusão: medido separadamente (tempo até o resultado ficar pronto).
Passo a passo — testando um fluxo assíncrono com 202
- Envie a requisição que dispara o processamento e valide o 202.
- Capture o identificador de acompanhamento (ex.: um
jobIdno corpo, ou uma URL de status em header/corpo). - Faça polling em um endpoint de status em intervalos controlados (com backoff para não sobrecarregar).
- Defina um timeout total do fluxo (ex.: “o job deve concluir em até 30 s”).
- Valide estados intermediários quando existirem (ex.: queued/running) e o estado final (success/failed).
# Exemplo conceitual de polling com backoff: timeout_total = 30s intervalo = 500ms enquanto (tempo < timeout_total): resp = GET /jobs/{jobId} se resp.status == 'done': validar resultado e sair se resp.status == 'failed': falhar e sair dormir(intervalo) intervalo = min(intervalo * 1.5, 5s)Respostas parciais: como tratar em critérios de confiabilidade
Algumas APIs podem retornar dados parciais (por exemplo, parte do conjunto disponível e indicação de que o restante está em processamento). Ao testar confiabilidade:
- Valide que a API sinaliza claramente a parcialidade (campo/flag/estado), em vez de retornar silenciosamente dados incompletos.
- Valide que o cliente consegue recuperar o restante por meio do mecanismo previsto (polling, paginação, continuação).
- Meça separadamente: tempo para a primeira resposta (parcial) e tempo para completar o conjunto.
Checklist prático de critérios iniciais (para colocar no pipeline)
- Por endpoint crítico: p95/p99 abaixo do orçamento.
- Payload dentro do máximo esperado (alerta para crescimento súbito).
- Paginação: limite máximo respeitado e performance aceitável no máximo permitido.
- Timeouts do cliente configurados e sem ocorrências em cenários normais.
- Teste específico de degradação: sob pressão leve, 429/503 aparecem quando aplicável e com comportamento consistente.
- Estabilidade: variação entre execuções dentro de faixa definida.
- Fluxos 202: medir aceitação (202) e conclusão (end-to-end) com polling/backoff e timeout total.