Evidências e observabilidade para testes de API: logs, correlação e diagnósticos

Capítulo 15

Tempo estimado de leitura: 10 minutos

+ Exercício

O que são evidências e observabilidade em testes de API

Em testes de API, evidência é o conjunto de informações registradas que permite entender e reproduzir um comportamento observado (sucesso, falha ou degradação). Observabilidade é a capacidade de responder perguntas sobre o que aconteceu e por quê, usando sinais como logs, métricas e traces (rastros distribuídos). Na prática, para quem testa, observabilidade significa: conseguir ligar uma falha vista no teste a um evento no servidor, em um horário específico, dentro de um ambiente específico, com um identificador que conecte tudo.

Uma evidência de qualidade reduz o “vai e volta” com desenvolvimento e operações, porque responde rapidamente: o que foi enviado, o que foi recebido, em que contexto e como rastrear no backend.

O que registrar como evidência (checklist essencial)

1) Request e response sanitizados (sem segredos)

Registre request/response completos o suficiente para reproduzir, mas sanitizados para não expor dados sensíveis. O objetivo é manter estrutura e valores relevantes, removendo ou mascarando segredos e PII.

  • Sanitizar: tokens, senhas, chaves, cookies, números de documento, e-mails, telefones, dados financeiros, etc.
  • Preservar: campos que influenciam a regra (ex.: tipo, status, flags, ids técnicos), e o formato do payload.
// Exemplo de request sanitizado (JSON) para evidência
{
  "method": "POST",
  "url": "https://api.exemplo.com/v1/orders",
  "headers": {
    "Content-Type": "application/json",
    "Accept": "application/json",
    "X-Correlation-Id": "c0a8012e-2b7f-4f2a-9b7b-9d3b2b4f6a10"
  },
  "body": {
    "customerId": "12345",
    "payment": {
      "cardToken": "***MASKED***"
    },
    "items": [
      {"sku": "ABC-001", "qty": 2}
    ]
  }
}
// Exemplo de response sanitizado
{
  "status": 500,
  "headers": {
    "Content-Type": "application/json",
    "X-Correlation-Id": "c0a8012e-2b7f-4f2a-9b7b-9d3b2b4f6a10"
  },
  "body": {
    "error": {
      "code": "INTERNAL_ERROR",
      "message": "Unexpected error"
    }
  }
}

2) Headers relevantes

Nem todos os headers são úteis como evidência. Priorize os que ajudam a reproduzir e diagnosticar:

  • Identidade e rastreio: X-Correlation-Id (ou equivalente), traceparent (W3C Trace Context), X-Request-Id.
  • Contexto de execução: User-Agent (cliente), X-Client-Version (se existir), X-Forwarded-For (quando relevante), Host.
  • Negociação/serialização: Content-Type, Accept (apenas se impactarem o problema).
  • Cache e concorrência (quando aplicável): If-Match, ETag, Cache-Control.

Evite registrar Authorization, Cookie e chaves de API em texto puro. Se precisar provar que houve autenticação, registre apenas “presente/ausente” e o tipo (ex.: “Bearer ***MASKED***”).

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

3) Correlation-ID (ID de correlação)

O Correlation-ID é um identificador único que você envia na requisição e que o servidor propaga nos logs (e idealmente em chamadas internas). Ele permite encontrar rapidamente, no backend, o que aconteceu com aquela requisição específica.

  • Ajuda a rastrear falhas em sistemas distribuídos.
  • Ajuda a diferenciar bug (lógica) de problema de ambiente (instabilidade, dependências fora, configuração, rede).
  • Reduz ambiguidade quando há alta concorrência (muitas requisições parecidas).

4) Timestamps e fuso horário

Registre timestamps em formato padronizado (ex.: ISO 8601 em UTC) para correlacionar com logs e métricas. Inclua:

  • Início e fim da chamada
  • Duração (latência observada)
  • Fuso (preferencialmente UTC)
// Exemplo de metadados de tempo
{
  "startedAt": "2026-01-26T13:45:12.345Z",
  "finishedAt": "2026-01-26T13:45:12.912Z",
  "durationMs": 567
}

5) Ambiente e contexto de execução

Muitas “falhas” são variações de ambiente. Sempre registre:

  • Ambiente: dev/hml/stg/prod (ou nome real)
  • Base URL e região (se multi-região)
  • Versão do serviço (build, commit, tag) quando disponível
  • Configuração relevante: feature flags, tenant, perfil do usuário (sem dados sensíveis)
  • Dependências (se conhecidas): serviço X/Y, fila, banco, provedor externo
ItemExemploPor que importa
Ambientestaging-euDiferenças de config e dados
Versãoorders-service 1.18.3 (commit abc123)Reproduzir em build específico
Tenant/ContatenantId=acmeRegras e dados variam por tenant
Feature flagnewPricing=trueComportamento muda por flag

Passo a passo: como coletar evidências úteis em um teste de API

Passo 1 — Gere e propague um Correlation-ID

Defina um padrão para o ID (UUID é suficiente) e envie em todas as requisições do teste. Se a API já gera um ID, capture o retornado e use-o como referência.

  • Envio: header X-Correlation-Id (ou o padrão da sua organização).
  • Validação: verifique se a resposta ecoa o mesmo ID (quando suportado).
// Exemplo (pseudo) de geração
X-Correlation-Id: 2f1c2b2a-6f2d-4b9a-9d6a-2a0d2f6c9a11

Passo 2 — Registre request/response com sanitização automática

Implemente uma camada de logging no seu cliente de teste (ou no framework) que:

  • Capture método, URL, query, headers relevantes e body
  • Masque campos e headers sensíveis
  • Trunque payloads muito grandes (com indicação de truncamento)
// Exemplo de regras de sanitização (lista de chaves)
SENSITIVE_HEADERS = ["authorization", "cookie", "x-api-key"]
SENSITIVE_FIELDS = ["password", "token", "cardNumber", "cardToken", "cpf", "ssn"]
MASK = "***MASKED***"

Passo 3 — Capture metadados de tempo e rede

Além do timestamp, registre informações que ajudam a separar falha funcional de falha de infraestrutura:

  • DNS/host resolvido (quando aplicável)
  • IP/cluster (se disponível via header de resposta)
  • Tempo de conexão vs tempo total (se o cliente expõe)
  • Timeout configurado

Passo 4 — Ao falhar, gere um “pacote de evidência” mínimo

Quando um teste falha, gere automaticamente um artefato (arquivo JSON/texto) contendo:

  • Correlation-ID
  • Request/response sanitizados
  • Timestamps e duração
  • Ambiente, base URL, versão do serviço (se disponível)
  • Asserção que falhou (o que era esperado vs obtido)
// Estrutura sugerida de pacote de evidência
{
  "testCaseId": "API-ORDERS-017",
  "environment": "staging-eu",
  "baseUrl": "https://api.exemplo.com",
  "serviceVersion": "orders-service 1.18.3",
  "correlationId": "2f1c2b2a-6f2d-4b9a-9d6a-2a0d2f6c9a11",
  "time": {
    "startedAt": "2026-01-26T13:45:12.345Z",
    "durationMs": 567
  },
  "request": { "method": "POST", "path": "/v1/orders", "headers": {"X-Correlation-Id": "..."}, "body": {"cardToken": "***MASKED***"} },
  "response": { "status": 500, "headers": {"X-Correlation-Id": "..."}, "body": {"error": {"code": "INTERNAL_ERROR"}} },
  "assertion": {
    "expected": "HTTP 201 com body contendo orderId",
    "actual": "HTTP 500 INTERNAL_ERROR"
  }
}

Como usar Correlation-ID para rastrear falhas e diagnosticar

Rastreamento no backend (fluxo mental)

Com o Correlation-ID em mãos, o fluxo típico de diagnóstico é:

  • 1) Encontrar o log de entrada (gateway/API) pelo ID
  • 2) Verificar validações iniciais (schema, autenticação, autorização, rate limit) e o status retornado
  • 3) Seguir logs/traces para chamadas internas (serviços e dependências)
  • 4) Identificar o ponto exato da falha (exceção, timeout, resposta inválida de dependência)

Mesmo sem acesso direto aos logs, fornecer o Correlation-ID no defeito permite que quem tem acesso encontre rapidamente o rastro.

Diferenciando bug de ambiente (heurísticas práticas)

SinalIndica maisComo evidenciar
Falha intermitente (passa/falha sem mudança)Ambiente/instabilidadeRegistrar frequência, horários, Correlation-IDs de múltiplas ocorrências
Timeouts e latência muito variávelAmbiente/dependênciaRegistrar durationMs, timeout configurado, status/erro de rede
Falha determinística com mesmo payloadBug funcionalFornecer exemplo mínimo reproduzível e passos consistentes
Erro concentrado em um nó/regiãoAmbiente/configuraçãoRegistrar headers de identificação de instância/cluster (se existirem)
Erro após deploy/feature flagBug/regressão ou configRegistrar versão do serviço e flags ativas

Quando coletar mais de um Correlation-ID

Em falhas intermitentes, um único ID pode não ser suficiente. Colete:

  • Um ID de uma execução que falhou
  • Um ID de uma execução equivalente que passou (mesmo endpoint e payload, se possível)
  • Horários próximos

Isso ajuda a comparar caminhos de execução e dependências.

Padrão de relatório de defeito focado em API

Um bom relatório de defeito em API é objetivo, reproduzível e rastreável. Use um template padronizado para reduzir omissões.

Template (copiar e preencher)

Resumo:
- [Serviço] [Endpoint] retorna [status/erro] ao [condição]

Ambiente:
- Ambiente: 
- Base URL: 
- Região/Cluster (se aplicável): 
- Versão do serviço/build: 
- Feature flags/tenant: 

Requisição:
- Método: 
- Endpoint (path): 
- Query params: 
- Headers relevantes (sanitizados): 
- Payload (sanitizado): 

Resultado esperado:
- Status HTTP esperado: 
- Corpo esperado (regra/contrato): 

Resultado obtido:
- Status HTTP obtido: 
- Corpo obtido (sanitizado): 
- Headers de resposta relevantes: 

Evidências e rastreio:
- Correlation-ID: 
- Timestamps (UTC): 
- Duração (ms): 
- Logs do cliente (se houver): 

Exemplo mínimo reproduzível:
- Passos (1..N):
- Dados mínimos para reproduzir:
- Observações sobre intermitência (frequência, janelas de tempo):

Exemplo preenchido (mínimo e reproduzível)

Resumo:
- POST /v1/orders retorna 500 ao criar pedido com item válido

Ambiente:
- Ambiente: staging-eu
- Base URL: https://api.exemplo.com
- Versão do serviço/build: orders-service 1.18.3 (commit abc123)
- Tenant: acme | Feature flag: newPricing=true

Requisição:
- Método: POST
- Endpoint: /v1/orders
- Headers: Content-Type: application/json; Accept: application/json; X-Correlation-Id: 2f1c2b2a-6f2d-4b9a-9d6a-2a0d2f6c9a11
- Payload (sanitizado): {"customerId":"12345","payment":{"cardToken":"***MASKED***"},"items":[{"sku":"ABC-001","qty":2}]}

Resultado esperado:
- Status: 201
- Body: conter orderId e status=CREATED

Resultado obtido:
- Status: 500
- Body: {"error":{"code":"INTERNAL_ERROR","message":"Unexpected error"}}

Evidências e rastreio:
- Correlation-ID: 2f1c2b2a-6f2d-4b9a-9d6a-2a0d2f6c9a11
- Timestamp (UTC): 2026-01-26T13:45:12.345Z
- Duração: 567ms

Exemplo mínimo reproduzível:
1) Enviar POST /v1/orders com o payload acima
2) Repetir 3 vezes (falha 3/3)
Observação: determinístico neste ambiente; em dev não reproduziu.

Critérios de qualidade de evidência (o que torna a evidência “boa”)

Critérios objetivos

  • Reprodutibilidade: alguém consegue reproduzir com os dados fornecidos (ou entender por que é intermitente).
  • Rastreabilidade: há Correlation-ID e timestamps para localizar logs/traces.
  • Completude mínima: inclui endpoint, método, payload, headers relevantes, status esperado/obtido.
  • Sanitização: não expõe segredos nem PII; mascaramento consistente.
  • Precisão: não há contradições (ex.: status no texto diferente do status no log).
  • Contexto de ambiente: base URL, ambiente, versão/build, flags/tenant quando influenciam.
  • Foco no sinal: evita excesso de ruído (logs gigantes sem recorte); destaca o que falhou.

Anti-padrões comuns (e como corrigir)

Anti-padrãoProblemaCorreção
“Deu erro 500” sem requestNão reproduz nem diagnosticaAdicionar request/response sanitizados + esperado/obtido
Sem Correlation-IDBackend não encontra o eventoGerar/enviar ID e registrar na evidência
Print com token/senhaRisco de segurançaSanitização automática e revisão
Payload enorme sem recorteRuído; difícil achar causaFornecer exemplo mínimo reproduzível
Sem ambiente/versão“Não reproduz aqui” vira impasseRegistrar base URL, ambiente, build, flags

Práticas recomendadas para padronizar evidências no time

Convenções de nomenclatura e armazenamento

  • Nomear artefatos com testCaseId, data/hora UTC e correlationId (ex.: API-ORDERS-017_20260126T134512Z_2f1c2b2a.json).
  • Armazenar evidências em local central com retenção definida (evitar espalhar em chats).
  • Separar evidência de execução bem-sucedida vs falha para comparação.

Campos padrão para logs do cliente de teste

Se você controla o cliente de teste, padronize um log estruturado (JSON) com campos fixos. Isso facilita busca e agregação.

// Log estruturado sugerido (por requisição)
{
  "level": "INFO",
  "event": "api_call",
  "testCaseId": "API-ORDERS-017",
  "correlationId": "2f1c2b2a-6f2d-4b9a-9d6a-2a0d2f6c9a11",
  "env": "staging-eu",
  "method": "POST",
  "path": "/v1/orders",
  "status": 500,
  "durationMs": 567,
  "timestamp": "2026-01-26T13:45:12.912Z"
}

Quando anexar evidências adicionais

Alguns cenários pedem evidências extras além de request/response:

  • Intermitência: anexar série temporal (lista de tentativas com timestamps, status e durations).
  • Dependência externa: registrar status/erro da dependência quando exposto (ex.: código de erro interno mapeado).
  • Problema de serialização: anexar payload bruto (sanitizado) e o tipo de encoding.
  • Problema de roteamento: anexar headers que identifiquem instância/edge (quando existirem).

Agora responda o exercício sobre o conteúdo:

Ao registrar evidências para diagnosticar uma falha em um teste de API, qual combinação torna a evidência mais rastreável e útil para correlacionar o teste com eventos no backend?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

A rastreabilidade depende de ligar o que o teste viu ao que o servidor registrou. Request/response sanitizados permitem reproduzir sem expor segredos, enquanto Correlation-ID e timestamps (UTC e duração) viabilizam correlacionar com logs/traces e identificar diferenças de ambiente e versão.

Capa do Ebook gratuito Testes de API: Conceitos Essenciais (REST, HTTP, Status Codes e Contratos)
100%

Testes de API: Conceitos Essenciais (REST, HTTP, Status Codes e Contratos)

Novo curso

15 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.