Como Rodar Testes de API Parametrizados com CSV e JSON

Testes de API parametrizados permitem executar um cenário em centenas de casos CSV ou JSON. Crie-o uma vez no Apidog e execute-o de forma *headless* na CI.

INEZA Felin-Michel

INEZA Felin-Michel

16 junho 2026

Como Rodar Testes de API Parametrizados com CSV e JSON

Apidog para empresas

Implantação local

SSO & RBAC

Conforme SOC 2

Explorar Apidog Enterprise

Você escreveu um teste de login. Ele passa. Então um colega de equipe faz a pergunta óbvia: ele passa para a conta bloqueada, o e-mail não verificado, a senha com um espaço no final, a string de injeção SQL que alguém eventualmente colará no campo? Agora você tem uma escolha. Copiar esse teste cinco vezes e mudar um valor em cada cópia, ou encontrar uma maneira de alimentar o mesmo teste com muitas linhas de entrada e deixá-lo executá-las todas.

A rota do copiar-colar é como a maioria das suítes de teste apodrece. Cinco testes quase idênticos se separam ao longo de um ano. Um recebe uma nova asserção, os outros não. Uma renomeação de campo quebra quatro deles silenciosamente. Você acaba mantendo cinco coisas que deveriam ser uma. Testes parametrizados corrigem isso na raiz: você escreve o teste uma vez e, em seguida, o aponta para uma tabela de entradas e saídas esperadas. Um cenário, centenas de casos, um único lugar para editar.

botão

O que realmente significa teste parametrizado

Testes parametrizados, às vezes chamados de testes baseados em dados (data-driven testing), separam a lógica de um teste dos dados contra os quais ele é executado. A lógica é a sequência de etapas: enviar uma requisição, verificar o código de status, validar um campo na resposta. Os dados são o conjunto de entradas e expectativas que você deseja que essa lógica execute.

Imagine um único cenário de teste para um endpoint de código de desconto. A lógica é sempre a mesma. Enviar POST /api/orders com um código e, em seguida, fazer asserções na resposta. Os dados mudam a cada caso:

código total_pedido status_esperado desconto_esperado
WELCOME10 100 200 10
WELCOME10 5 422 0
EXPIRED 100 410 0
(vazio) 100 400 0
FAKE123 100 404 0

Cinco linhas, cinco comportamentos distintos, um teste. O executor itera sobre as linhas. A cada passagem, ele vincula os valores das colunas a variáveis, dispara a requisição e verifica as asserções em relação às expectativas daquela linha. Quando a linha 3 falha porque o código expirado retornou 200 em vez de 410, você obtém uma falha clara apontando para uma linha. Você não sai procurando em cinco arquivos de teste separados para descobrir qual cópia quebrou.

Este padrão importa mais nas extremidades. A cobertura de 'caminho feliz' é fácil de escrever e raramente captura o bug que te acorda às 2 da manhã. Os bugs vivem nos casos de limite: a string vazia, o número negativo, o nome unicode, o token expirado, o valor que está um centavo acima do limite. A parametrização torna a adição de um caso de limite tão barata quanto adicionar uma linha a uma planilha.

Por que um arquivo de dados separado supera valores hardcoded

Você poderia hardcodar cada caso diretamente no teste. A maioria das pessoas começa por aí. O problema aparece mais tarde.

Quando os dados vivem no teste, um não-engenheiro não pode contribuir com casos. Seu líder de QA conhece quinze entradas complicadas que já quebraram este endpoint antes, mas eles não podem adicioná-las sem editar o código e abrir um pull request. Quando os dados vivem em um CSV, eles editam uma planilha e a commitam. A barreira cai para perto de zero.

Um arquivo separado também mantém seu cenário de teste legível. Um teste que percorre um arquivo externo é curto: uma requisição, algumas asserções, pronto. Um teste com trinta casos inline é uma parede de repetição que ninguém quer tocar. E quando você precisa gerar casos programaticamente, digamos, mil linhas extraídas de logs de produção, um arquivo é a única opção sensata. Você não pode colar mil casos no corpo de um teste.

O formato que você escolhe depende da forma dos seus dados. Casos planos e tabulares se encaixam em CSV. Payloads aninhados ou estruturados se encaixam em JSON. Ambos são entradas de primeira classe no executor do Apidog, então a escolha é sobre seus dados, não sobre limitações da ferramenta.

Configurando seu arquivo de dados

Comece com CSV para casos tabulares. A linha de cabeçalho nomeia suas variáveis; cada linha abaixo é uma iteração. Aqui está a tabela de códigos de desconto como um arquivo real, discount-cases.csv:

código,total_pedido,status_esperado,desconto_esperado
WELCOME10,100,200,10
WELCOME10,5,422,0
EXPIRED,100,410,0
,100,400,0
FAKE123,100,404,0

Cada cabeçalho de coluna se torna uma variável que você referencia dentro do teste. No corpo da requisição, você escreve {{code}} e {{order_total}}; nas asserções, você compara com {{expected_status}} e {{expected_discount}}. O executor faz a vinculação linha por linha.

Quando suas entradas são aninhadas, use JSON. Um array de objetos, um objeto por iteração, permite que cada caso carregue dados estruturados que seriam difíceis de nivelar em colunas. Aqui está user-cases.json para um endpoint de criação de usuário onde o payload tem campos aninhados:

[
  {
    "cenário": "perfil completo válido",
    "user": {
      "email": "ada@example.com",
      "roles": ["admin", "billing"],
      "profile": { "país": "US", "fuso_horário": "America/New_York" }
    },
    "status_esperado": 201
  },
  {
    "cenário": "e-mail ausente",
    "user": {
      "email": "",
      "roles": ["viewer"],
      "profile": { "país": "GB", "fuso_horário": "Europe/London" }
    },
    "status_esperado": 400
  },
  {
    "cenário": "função desconhecida",
    "user": {
      "email": "grace@example.com",
      "roles": ["wizard"],
      "profile": { "país": "CA", "fuso_horário": "America/Toronto" }
    },
    "status_esperado": 422
  }
]

Dentro do teste, você referencia os valores estruturados com a mesma sintaxe {{user}}, {{expected_status}}, e o Apidog entrega os campos de cada objeto para a iteração. A coluna scenario é um rótulo para você mesmo; ela aparece no relatório para que uma iteração falha seja lida como “função desconhecida” em vez de “iteração 3”.

Algumas regras evitam que arquivos de dados te causem problemas:

Construindo o cenário parametrizado no Apidog

No aplicativo Apidog, construa o cenário de teste uma vez como qualquer outro. Adicione a requisição ao seu endpoint. No corpo, troque os valores literais por referências de variáveis: {{code}}, {{order_total}}, e assim por diante. Estas são as colunas do seu arquivo de dados.

Em seguida, adicione as asserções que leem do mesmo arquivo. Para o exemplo do desconto, você afirmaria que o status da resposta é igual a {{expected_status}} e que o campo de desconto no corpo JSON é igual a {{expected_discount}}. Como tanto a entrada quanto a saída esperada vêm da linha, a mesma lógica de asserção valida cada caso corretamente. Se você nunca escreveu asserções no Apidog antes, asserções de API: um guia prático cobre os padrões, e como definir asserções e extrair variáveis de uma resposta JSON mostra o lado do JSONPath em detalhes.

Para conectar os dados, abra as configurações de execução do cenário de teste e anexe seu arquivo CSV ou JSON como a fonte de dados de iteração. O Apidog lê o arquivo, conta as linhas e executa o cenário uma vez por linha, vinculando as colunas de cada linha às variáveis correspondentes. Execute-o dentro do aplicativo e você obterá um detalhamento por iteração: quais linhas passaram, quais falharam e o valor real versus esperado para cada asserção falha.

É aqui também que a parametrização se compõe com o restante da sua suíte. Um cenário parametrizado ainda é um cenário, então você pode agrupar vários deles em uma suíte de testes e executar todo o conjunto como um único trabalho. O loop orientado a dados lida com a amplitude dentro de um único endpoint; a suíte de testes lida com a cobertura entre endpoints.

Executando pela linha de comando

O aplicativo é onde você constrói e depura. CI é onde o teste prova seu valor, executando em cada pull request sem que ninguém clique em um botão. Essa passagem é para o que o CLI do Apidog serve. Ele pega o cenário que você construiu no aplicativo e o executa sem interface gráfica a partir de um terminal, com os mesmos dados de iteração.

O CLI é distribuído como um pacote npm. Instale-o globalmente:

npm install -g apidog-cli

O binário é apidog, então todo comando começa com apidog run. Uma execução básica aponta para um cenário por ID e um ambiente por ID:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r cli

Para executar esse cenário a partir de um arquivo de dados, adicione a flag iteration-data. Ela aceita um caminho para um arquivo JSON ou CSV:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 \
  -d ./discount-cases.csv -r cli,junit --out-dir ./test-reports

A flag -d (forma longa --iteration-data) é o coração das execuções parametrizadas a partir da linha de comando. O Apidog lê o arquivo, executa o cenário uma vez por linha e relata cada iteração. Troque discount-cases.csv por user-cases.json e a mesma flag lida com o array JSON; o executor detecta o formato a partir do arquivo. Trate o token de acesso como uma senha e armazene-o como um segredo de CI, nunca em um arquivo commitado. É por isso que todo exemplo referencia $APIDOG_ACCESS_TOKEN em vez de um valor literal.

Algumas flags combinam naturalmente com execuções parametrizadas:

Se você quiser a lista autoritária e atual de flags para sua versão instalada, execute apidog run --help. O CLI imprime cada opção com sua forma curta e longa.

Integrando execuções parametrizadas no CI

A razão para investir em testes parametrizados é que eles se pagam automaticamente. Aqui está um trabalho do GitHub Actions que instala o CLI e executa um cenário baseado em CSV em cada pull request:

name: Testes de API
on: [pull_request]

jobs:
  api-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Instalar Apidog CLI
        run: npm install -g apidog-cli
      - name: Executar testes de API parametrizados
        env:
          APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
        run: |
          apidog run --access-token $APIDOG_ACCESS_TOKEN \
            -t 605067 -e 1629989 \
            -d ./tests/discount-cases.csv \
            -r cli,junit --out-dir ./test-reports
      - name: Fazer upload do relatório
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: api-test-report
          path: ./test-reports

O token vem de secrets.APIDOG_ACCESS_TOKEN, configurado uma vez nas configurações do seu repositório. O reporter junit escreve XML que a maioria dos dashboards de CI transforma em uma árvore de resultados por iteração, então uma linha falha aparece como um teste falho nomeado em vez de uma parede de texto de log. O if: always() na etapa de upload significa que você mantém o relatório mesmo quando a execução falha, que é exatamente quando você o deseja. Para um guia mais aprofundado sobre o lado do Actions, veja como automatizar testes de API no GitHub Actions.

O mesmo cenário e o mesmo arquivo de dados são executados em qualquer sistema de CI. GitLab CI, Jenkins, CircleCI e os demais se resumem aos mesmos três passos: instalar Node e o CLI, expor o token como uma variável de ambiente, chamar apidog run com -d. Não há reescrita de seus testes por plataforma.

Comparando abordagens de testes parametrizados

Apidog não é a única maneira de executar testes de API orientados a dados. Vale a pena conhecer o cenário para escolher a opção certa.

O Postman e seus executores também suportam arquivos de dados. Com o Collection Runner do Postman ou a ferramenta de linha de comando Newman, você anexa um arquivo CSV ou JSON e referencia variáveis {{column}} nas requisições, muito parecido com o padrão aqui. É uma abordagem capaz e bem documentada. A desvantagem é que sua lógica de teste reside em scripts JavaScript de pré-requisição e teste, então, à medida que suas asserções aumentam, você mantém mais código. Se você estiver avaliando especificamente os executores de linha de comando, Postman CLI vs Newman detalha as diferenças.

Frameworks 'code-first' como pytest com @pytest.mark.parametrize, @ParameterizedTest do JUnit, ou REST Assured dão a você controle total da linguagem de programação. Eles são a escolha certa quando sua lógica de teste realmente precisa de código: configuração complexa, geração de dados personalizada, acoplamento estreito a uma base de código de teste existente. O custo é que cada caso vive no código, então não-engenheiros não podem contribuir, e você mantém a parte de HTTP por conta própria.

O diferencial do Apidog é que o cenário é visual e os dados são externos, então a lógica permanece legível e os casos ficam abertos a qualquer pessoa que possa editar uma planilha, enquanto o mesmo cenário ainda é executado sem interface gráfica no CI. Se você está escolhendo especificamente uma ferramenta para execuções orientadas a dados CSV e JSON, a comparação em qual ferramenta para testes de API orientados a dados com CSV ou JSON aprofunda-se nas vantagens e desvantagens. Nenhuma dessas opções está errada. Combine a abordagem com quem escreve os casos e quanta lógica personalizada cada caso precisa.

Um fluxo de trabalho prático que escala

Veja como isso se parece uma vez que faz parte da rotina da sua equipe.

Comece pequeno. Escolha um endpoint que já te causou problemas antes. Escreva o cenário único no Apidog com referências de variáveis na requisição e o resultado esperado nas asserções. Crie um CSV com três linhas: um caminho feliz, uma falha conhecida, um caso de limite. Execute-o no aplicativo até que todas as três iterações se comportem conforme o esperado.

Depois, aumente os dados, não o teste. Toda vez que um relatório de bug chega, adicione a entrada que o causou como uma nova linha com sua saída esperada correta. O bug se torna um caso de regressão permanente e você nunca escreveu um novo teste, você adicionou uma linha a um arquivo. Ao longo de alguns meses, o arquivo acumula a complexidade do mundo real que seu endpoint realmente enfrenta.

Finalmente, automatize. Inclua o comando apidog run -d no CI para que toda a tabela seja executada em cada pull request. Agora, uma mudança que quebra o caminho do código expirado falha a build no momento em que é enviada, com uma iteração nomeada apontando diretamente para a linha quebrada.

O ganho cumulativo é a manutenção. Quando a forma da resposta do endpoint muda, você corrige a asserção uma vez e todos os casos pegam a correção. Quando você precisa de mais cinquenta casos, você adiciona cinquenta linhas. A lógica do teste permanece uma coisa única, pequena e legível, não importa o quão ampla sua cobertura se torne.

Perguntas frequentes

Qual a diferença entre teste parametrizado e teste baseado em dados (data-driven testing)? Eles descrevem a mesma ideia e as pessoas usam os termos de forma intercambiável. Ambos significam executar um teste repetidamente com diferentes entradas e saídas esperadas fornecidas de fora do teste. “Parametrizado” se baseia no mecanismo de vinculação de parâmetros; “baseado em dados” se baseia na fonte de dados externa. Na prática, trate-os como sinônimos.

Devo usar CSV ou JSON para meu arquivo de dados? Combine o formato com a forma dos seus dados. Casos planos e tabulares onde cada linha tem as mesmas colunas simples se encaixam em CSV, e CSV é mais fácil para não-engenheiros editarem em uma planilha. Payloads aninhados ou estruturados, como um corpo de requisição com arrays e sub-objetos, se encaixam em JSON. O Apidog lê ambos como dados de iteração, então escolha o que melhor representa seus casos sem contorção.

Centenas de iterações vão desacelerar meu pipeline? Cada linha é uma execução do cenário, então o tempo total escala com a contagem de linhas vezes a latência por requisição. Para a maioria dos testes de API, isso é segundos, não minutos. Se um grande conjunto de dados estender sua build, divida-o: execute um subconjunto rápido de 'smoke tests' em cada pull request e a tabela completa em um trabalho noturno ou de pré-lançamento. O mesmo cenário e arquivo impulsionam ambos; apenas o subconjunto de dados muda.

Como manter segredos fora dos meus arquivos de dados e da configuração de teste? Mantenha as credenciais completamente fora do arquivo de dados. Tokens e senhas pertencem a variáveis de ambiente ou ao armazenamento de segredos do seu sistema de CI, referenciados como $APIDOG_ACCESS_TOKEN e similares. O arquivo de dados deve conter entradas de teste e resultados esperados, não material de autenticação. Qualquer pessoa que possa ler o repositório pode ler o CSV, então trate-o dessa forma.

Posso executar o mesmo cenário parametrizado contra staging e produção? Sim. Mantenha o cenário e o arquivo de dados fixos, e mude os ambientes com a flag -e. Aponte uma verificação de pull request para o ambiente de staging e um 'smoke test' pós-deploy para produção usando o mesmo ID de cenário e os mesmos dados, apenas um ID de ambiente diferente. Essa é a razão pela qual ambiente e dados são entradas separadas.

Conclusão

O teste de API parametrizado transforma a cobertura de uma tarefa de copiar e colar em uma tarefa de entrada de dados. Você escreve o teste uma vez, descreve cada caso como uma linha em um arquivo CSV ou JSON, e deixa o executor fazer o resto. A lógica permanece pequena e legível, os casos permanecem abertos a qualquer pessoa da equipe, e o CI executa toda a tabela a cada mudança.

O Apidog oferece o construtor de cenário visual para autoria, arquivos CSV e JSON externos para os dados, e o comando apidog run -d para execução sem interface gráfica em qualquer sistema de CI. Construa um cenário, aponte-o para uma tabela crescente de casos, e sua cobertura de teste se amplia toda vez que alguém adiciona uma linha. Baixe o Apidog e transforme seu próximo teste pontual instável em um cenário parametrizado que escala.

botão

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs