DEV Community

Cover image for Testes de Regressão de API: Como Identificar Erros Críticos Antecipadamente
Lucas
Lucas

Posted on • Originally published at apidog.com

Testes de Regressão de API: Como Identificar Erros Críticos Antecipadamente

Você envia uma pequena alteração para um endpoint. O código compila, o recurso funciona e você implanta. Dois dias depois, um cliente móvel começa a travar porque um campo que antes era string agora é um objeto. A mudança parecia local. Não era.

Experimente o Apidog hoje

Teste de regressão de API serve para detectar esse tipo de quebra antes que ela chegue aos consumidores. A ideia é simples: você salva um conjunto de requisições e asserções que representam o comportamento atual da API e executa esse conjunto a cada alteração. Se um código de status, formato de resposta, campo obrigatório ou valor contratual mudar, o teste falha e aponta onde ocorreu a regressão.

O que é teste de regressão de API

Teste de regressão significa reexecutar testes que já passaram para confirmar que o comportamento existente continua válido após uma alteração.

Em APIs, esse comportamento é o contrato HTTP usado pelos consumidores:

  • Rotas disponíveis
  • Métodos HTTP
  • Códigos de status
  • Estrutura da resposta
  • Tipos dos campos
  • Campos obrigatórios
  • Valores com significado contratual

APIs regridem por motivos comuns:

  • Um campo JSON é renomeado
  • Um 200 vira 204
  • Uma validação nova rejeita entradas antes aceitas
  • Uma atualização de ORM muda o formato de datas
  • Uma dependência altera mensagens de erro
  • Um campo obrigatório deixa de ser retornado

Essas quebras raramente aparecem como erro de compilação. Elas aparecem como integrações quebradas.

O foco do teste de regressão de API não é testar todo o sistema. É proteger a superfície HTTP à qual outros sistemas se acoplam.

O que usar como baseline

O baseline é o comportamento esperado que será comparado nas próximas execuções.

Ele deve cobrir o que quebraria um consumidor real, sem travar o teste em dados voláteis.

Use estas quatro camadas como referência.

1. Códigos de status

Cada endpoint deve retornar um status conhecido para entradas conhecidas.

Exemplos de regressão:

POST /users retornava 201 e passou a retornar 200
GET /users/42 retornava 200 e passou a retornar 500
DELETE /users/42 retornava 204 e passou a retornar 404
Enter fullscreen mode Exit fullscreen mode

2. Esquema de resposta

Valide estrutura e tipos:

{
  "id": 42,
  "email": "alice@example.com",
  "status": "active",
  "roles": ["admin"]
}
Enter fullscreen mode Exit fullscreen mode

Asserções úteis:

body.id é number
body.email é string
body.status é string
body.roles é array
Enter fullscreen mode Exit fullscreen mode

Mudanças como estas devem falhar:

- "email": "alice@example.com"
+ "email": { "value": "alice@example.com" }
Enter fullscreen mode Exit fullscreen mode

3. Campos-chave

Não valide todos os valores. Valide os que têm significado contratual.

Bons candidatos:

  • id deve existir
  • status deve estar em um enum conhecido
  • total deve ser número
  • email deve ter formato de e-mail
  • items deve ser array

Exemplo:

body.status é um de ["active", "pending", "suspended"]
Enter fullscreen mode Exit fullscreen mode

4. Contrato OpenAPI

Compare a resposta real com a especificação OpenAPI.

Se a especificação diz que email é obrigatório e a API deixa de retorná-lo, isso deve falhar.

Para aprofundar essa abordagem, veja teste de contrato de API.

Exemplo de baseline para um endpoint

Um baseline mínimo para GET /v1/users/42 poderia ser:

GET /v1/users/42 -> 200

Asserções:
- body.id está presente
- body.id é number
- body.email está presente
- body.email é string
- body.email corresponde ao formato de e-mail
- body.status é um de ["active", "pending", "suspended"]
- body.roles é array
- response time < 800 ms
Enter fullscreen mode Exit fullscreen mode

Essas verificações protegem o contrato sem depender de valores dinâmicos.

Evite isto:

body.createdAt == "2026-01-01T10:00:00Z"
Enter fullscreen mode Exit fullscreen mode

Prefira isto:

body.createdAt é string
body.createdAt segue formato ISO 8601
Enter fullscreen mode Exit fullscreen mode

Para mais exemplos de verificações em respostas, veja asserções de API.

Teste manual vs. automatizado

Você pode testar regressão manualmente: abrir um cliente de API, reenviar requisições salvas e inspecionar respostas.

Isso funciona para poucos endpoints. Depois, quebra por três motivos:

  1. Pessoas esquecem de executar os testes
  2. Casos repetitivos são ignorados
  3. O teste não roda automaticamente em pull requests, merges ou deploys

Automatizar remove essa decisão humana. O conjunto roda sempre.

Critério Manual Automatizado
Executa em cada alteração Não, depende da disciplina Sim
Cobertura Poucos endpoints Conjunto completo
Custo por execução Tempo humano Computação
Roda de madrugada Não Sim
Esforço inicial Baixo Moderado

Para qualquer API usada por clientes, apps móveis, parceiros ou outros serviços, automatize.

Como construir um conjunto de regressão reutilizável

Um conjunto de regressão é um grupo de requisições salvas com asserções.

A meta é:

  • Criar uma vez
  • Executar sempre
  • Estender quando novos endpoints ou bugs aparecerem

1. Agrupe por recurso

Organize por área da API:

/users
/orders
/payments
/auth
Enter fullscreen mode Exit fullscreen mode

Exemplo:

Regression Suite
├── Users
│   ├── GET /users/{id}
│   ├── POST /users
│   └── PATCH /users/{id}
├── Orders
│   ├── GET /orders/{id}
│   └── POST /orders
└── Auth
    └── POST /login
Enter fullscreen mode Exit fullscreen mode

Isso facilita identificar qual grupo observar quando um serviço muda.

2. Use variáveis de ambiente

Não codifique valores como URL base, tokens ou IDs fixos em cada requisição.

Use variáveis:

{{baseUrl}}
{{accessToken}}
{{tenantId}}
{{userId}}
Enter fullscreen mode Exit fullscreen mode

Exemplo de ambientes:

local:
  baseUrl = http://localhost:3000

staging:
  baseUrl = https://staging.api.example.com

production:
  baseUrl = https://api.example.com
Enter fullscreen mode Exit fullscreen mode

Assim, o mesmo conjunto roda em local, staging ou produção mudando apenas o ambiente.

3. Encadeie requisições

Fluxos reais normalmente dependem de respostas anteriores.

Exemplo CRUD:

POST /users
  extrai body.id como userId

GET /users/{{userId}}
  valida dados criados

PATCH /users/{{userId}}
  atualiza status

DELETE /users/{{userId}}
  remove recurso
Enter fullscreen mode Exit fullscreen mode

Esse tipo de fluxo detecta regressões que não aparecem em testes isolados.

Essa prática se aproxima do teste de integração de API, porque valida a sequência entre endpoints.

4. Use dados para cobrir casos de borda

Em vez de criar várias requisições quase iguais, use uma tabela de dados.

Exemplo CSV:

email,expectedStatus
alice@example.com,201
bob@test.co,201
not-an-email,422
,422
a@b,422
Enter fullscreen mode Exit fullscreen mode

A mesma requisição roda cinco vezes, cada uma com entrada e status esperado diferentes.

Exemplo de lógica do teste:

POST /users
body.email = {{email}}

Asserção:
response.status == {{expectedStatus}}
Enter fullscreen mode Exit fullscreen mode

Adicione uma nova linha quando encontrar um novo caso de borda. Você aumenta cobertura sem duplicar requisições.

5. Mantenha o conjunto rápido

Um conjunto lento será ignorado.

Boas práticas:

  • Rode apenas o conjunto principal em pull requests
  • Deixe fluxos longos para execução noturna
  • Simule serviços externos lentos
  • Evite dependência de dados instáveis
  • Paralelize requisições independentes quando a ferramenta permitir

Um bom objetivo para PRs é manter o conjunto principal em poucos minutos.

Como executar o conjunto na CI

Um conjunto salvo apenas no seu laptop não protege o repositório.

Execute os testes nos eventos que podem introduzir regressões:

  • Pull requests
  • Merges no branch principal
  • Deploys para staging
  • Deploys para produção, quando aplicável

O padrão é:

  1. Instalar um runner headless
  2. Apontar para o conjunto salvo
  3. Executar contra um ambiente
  4. Fazer a build falhar se alguma asserção falhar
  5. Publicar relatório

O Apidog fornece o apidog-cli para isso.

Instale com Node:

npm install -g apidog-cli
Enter fullscreen mode Exit fullscreen mode

Execute um cenário, pasta ou conjunto salvo pelo ID:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t 123456 \
  -e 789012 \
  -r cli,html,junit
Enter fullscreen mode Exit fullscreen mode

Parâmetros:

  • --access-token: autentica a execução. Armazene como segredo da CI.
  • -t: ID do cenário, pasta ou conjunto.
  • -e: ID do ambiente.
  • -r: formatos de relatório.

Formatos comuns:

cli    imprime resultado no console
html   gera relatório legível
junit  gera XML para a CI exibir testes aprovados/falhos
Enter fullscreen mode Exit fullscreen mode

Exemplo com GitHub Actions

name: API Regression

on: [pull_request]

jobs:
  regression:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-node@v6
        with:
          node-version: '22'

      - name: Install Apidog CLI
        run: npm install -g apidog-cli

      - name: Run API regression suite
        run: |
          apidog run \
            --access-token "$APIDOG_ACCESS_TOKEN" \
            -t 123456 \
            -e 789012 \
            -r cli,junit
        env:
          APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

Se uma asserção falhar, o runner retorna código diferente de zero e o job fica vermelho. O pull request deve ser bloqueado até a regressão ser corrigida ou explicitamente aceita.

Para exemplos completos de pipeline, veja Apidog CLI para CI/CD e como automatizar testes de API no GitHub Actions.

Executando com arquivo de dados

Se o cenário usa dados externos, passe o arquivo com -d:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t 123456 \
  -e 789012 \
  -d ./test-data/emails.csv \
  -r cli,junit
Enter fullscreen mode Exit fullscreen mode

Exemplo de estrutura:

test-data/
└── emails.csv
Enter fullscreen mode Exit fullscreen mode

Com isso, uma única requisição pode ser executada várias vezes com entradas diferentes.

Executando testes de um branch específico

Se você mantém versões diferentes do conjunto em branches, use --branch:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t 123456 \
  -e 789012 \
  --branch feature/new-user-api \
  -r cli,junit
Enter fullscreen mode Exit fullscreen mode

Para manter histórico de execuções na nuvem, adicione:

--upload-report
Enter fullscreen mode Exit fullscreen mode

Exemplo:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t 123456 \
  -e 789012 \
  -r cli,junit \
  --upload-report
Enter fullscreen mode Exit fullscreen mode

Use diferenciação de esquema para detectar quebras antes do deploy

Asserções detectam regressões na API em execução. A diferenciação de esquema detecta regressões na especificação.

O fluxo é:

  1. A especificação OpenAPI fica versionada no repositório
  2. Um pull request altera a especificação
  3. A CI compara a nova versão com a anterior
  4. Mudanças são classificadas como seguras ou incompatíveis

Exemplos de mudanças normalmente seguras:

Adicionar campo opcional
Adicionar novo endpoint
Adicionar novo valor opcional
Enter fullscreen mode Exit fullscreen mode

Exemplos de mudanças incompatíveis:

Remover campo
Renomear campo
Alterar tipo de string para object
Tornar campo opcional obrigatório
Remover valor de enum
Alterar código de status esperado
Enter fullscreen mode Exit fullscreen mode

A diferenciação ajuda o revisor a ver algo como:

Breaking change: removed response property user.phone
Enter fullscreen mode Exit fullscreen mode

em vez de revisar manualmente uma parede de YAML.

Combine isso com testes de contrato contra a API ao vivo:

  • A especificação diz o que deve acontecer
  • A API real é validada contra essa especificação
  • Se código e contrato divergirem, o teste falha

Mudanças incompatíveis nem sempre são bugs. Às vezes são intencionais. O ponto é torná-las explícitas e passar por versionamento, comunicação e descontinuação.

Para esse processo, veja como versionar e descontinuar APIs em escala.

Como o Apidog ajuda nesse fluxo

O Apidog reúne design de API, cenários de teste, asserções e execução headless em CI.

Na prática, você pode:

  1. Criar cenários visualmente
  2. Encadear requisições
  3. Extrair valores de uma resposta para a próxima
  4. Adicionar asserções de status, esquema e campos
  5. Validar respostas contra o esquema salvo do endpoint
  6. Executar cenários com dados CSV ou JSON
  7. Rodar tudo na CI com apidog-cli

Exemplo de fluxo:

POST /users
  salva body.id em userId

GET /users/{{userId}}
  valida status 200
  valida body.id
  valida body.email
  valida schema

PATCH /users/{{userId}}
  valida status 200
  valida body.status

DELETE /users/{{userId}}
  valida status 204
Enter fullscreen mode Exit fullscreen mode

O apidog-cli não é um cliente interativo nem um gerador de carga. Ele tem um escopo específico: reproduzir conjuntos salvos de forma headless e reportar o resultado.

Para um fluxo scriptado completo, veja o guia de pipeline de CI/CD do Apidog CLI.

Fluxo inicial para implementar esta semana

Use este plano se você ainda não tem regressão automatizada de API.

1. Escolha os cinco endpoints mais chamados

Comece pelos endpoints com maior impacto:

GET /users/{id}
POST /login
GET /orders/{id}
POST /orders
GET /me
Enter fullscreen mode Exit fullscreen mode

O risco costuma estar onde há mais tráfego e mais consumidores.

2. Crie uma requisição salva por endpoint

Para cada endpoint, adicione pelo menos:

- Código de status esperado
- Validação de esquema
- Dois ou três campos-chave
Enter fullscreen mode Exit fullscreen mode

Exemplo:

GET /orders/{{orderId}}

Asserções:
- status == 200
- body.id é string
- body.total é number
- body.status é um de ["created", "paid", "cancelled"]
- body.items é array
Enter fullscreen mode Exit fullscreen mode

3. Adicione um fluxo encadeado

Escolha o recurso principal e teste o ciclo completo:

Criar -> Ler -> Atualizar -> Excluir
Enter fullscreen mode Exit fullscreen mode

Exemplo:

POST /products
GET /products/{{productId}}
PATCH /products/{{productId}}
DELETE /products/{{productId}}
Enter fullscreen mode Exit fullscreen mode

4. Adicione teste orientado a dados

Escolha um endpoint com validação forte, como cadastro ou pagamento.

Exemplo:

name,email,expectedStatus
Alice,alice@example.com,201
Bob,bob@test.co,201
Invalid,not-an-email,422
Empty,,422
Enter fullscreen mode Exit fullscreen mode

5. Conecte à CI

Adicione um job que:

- instala apidog-cli
- executa o conjunto
- gera relatório JUnit
- falha o pull request se houver regressão
Enter fullscreen mode Exit fullscreen mode

6. Transforme bugs escapados em testes

Quando uma regressão chegar à produção:

  1. Corrija o bug
  2. Reproduza o caso no conjunto de regressão
  3. Adicione uma asserção
  4. Garanta que o mesmo bug não escape novamente

Esse é o ciclo que torna o conjunto mais forte com o tempo.

FAQ

Como o teste de regressão de API difere do teste de regressão geral?

Teste de regressão geral verifica o comportamento do sistema como um todo, incluindo UI, lógica de negócio e integrações internas.

Teste de regressão de API foca na superfície HTTP:

  • Rotas
  • Métodos
  • Códigos de status
  • Esquemas de resposta
  • Campos obrigatórios
  • Valores contratuais

Esse foco mantém o conjunto rápido o suficiente para rodar em cada pull request.

Com que frequência devo executar o conjunto?

Execute em toda alteração que possa afetar a API.

Na prática:

  • Em cada pull request
  • Em cada merge no branch principal
  • Antes de deploys importantes

Mantenha um conjunto rápido para PRs e deixe fluxos longos para execuções noturnas.

O que devo afirmar para evitar testes frágeis?

Afirme o que quebraria um consumidor.

Boas asserções:

status == 200
body.id existe
body.id é string
body.status está em enum conhecido
body.createdAt segue formato ISO 8601
Enter fullscreen mode Exit fullscreen mode

Evite travar valores voláteis:

body.createdAt == "2026-01-01T10:00:00Z"
response.time == 132 ms
Enter fullscreen mode Exit fullscreen mode

Prefira validar tipo, formato e limites.

Posso executar regressão de API sem escrever código?

Sim. Ferramentas como o Apidog permitem criar cenários e asserções visualmente. Depois, o apidog-cli executa esses cenários na CI sem exigir um harness de teste escrito à mão.

Como lidar com mudanças intencionais que quebram compatibilidade?

Não trate como surpresa.

Use um processo explícito:

  1. Detecte a quebra via diff de esquema
  2. Revise a mudança no pull request
  3. Versione o endpoint se necessário
  4. Comunique consumidores
  5. Deprecie o comportamento antigo
  6. Atualize o baseline deliberadamente

O objetivo não é impedir toda mudança. É impedir que mudanças incompatíveis cheguem aos consumidores sem controle.

Top comments (0)