O que é data-driven testing no Collection Runner
Data-driven testing (teste orientado a dados) é uma abordagem em que você executa o mesmo conjunto de requisições e testes várias vezes, mudando apenas os dados de entrada a cada iteração. No Postman, isso acontece principalmente no Collection Runner: você seleciona uma coleção (ou uma pasta), escolhe um arquivo de dados (CSV ou JSON) e o Runner executa as requisições repetidamente, uma vez por linha (CSV) ou por item (JSON). A grande vantagem é reduzir duplicação: em vez de criar múltiplas requests quase iguais, você mantém uma única request “parametrizada” e alimenta variações por arquivo de dados. Isso é especialmente útil para cobrir combinações de inputs, validar regras de negócio com diferentes perfis e executar baterias de regressão com massa de dados controlada.
Como o Collection Runner usa os dados (CSV e JSON)
No Runner, cada iteração carrega um “registro” do arquivo de dados e expõe seus campos como variáveis acessíveis durante a execução. No Postman, essas variáveis de dados são referenciadas com a sintaxe de template: {{nomeDoCampo}}. Se o arquivo for CSV, os nomes dos campos vêm do cabeçalho (primeira linha). Se for JSON, os nomes vêm das chaves de cada objeto dentro de um array. Em ambos os casos, a cada iteração o Postman substitui {{campo}} pelo valor correspondente daquele registro. Isso permite parametrizar URL, query params, headers e body, além de usar esses valores em scripts de pré-request e testes.
Diferença prática entre CSV e JSON
CSV é ótimo para dados tabulares simples: combinações de campos em colunas, fácil de editar em planilhas e revisar rapidamente. JSON é melhor quando você precisa de estruturas aninhadas (objetos dentro de objetos), listas, ou quando quer representar payloads complexos com fidelidade. No Runner, ambos funcionam bem; a escolha depende do formato do dado e do nível de complexidade do payload.
Preparando uma coleção para receber dados do Runner
Para que o data-driven testing funcione, suas requests precisam estar “prontas para receber parâmetros”. Isso significa substituir valores fixos por placeholders do arquivo de dados. Por exemplo, em vez de um body com email fixo, você usa {{email}}. Em vez de um query param fixo de paginação, você usa {{page}}. O mesmo vale para headers customizados e partes do path.
Exemplo de placeholders no body
Imagine uma request que cria um usuário. Em vez de escrever valores fixos, você parametriza:
Continue em nosso aplicativo
Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.
ou continue lendo abaixo...Baixar o aplicativo
{ "name": "{{name}}", "email": "{{email}}", "password": "{{password}}", "role": "{{role}}" }Com isso, a mesma request pode ser executada dezenas de vezes com diferentes combinações de dados, sem duplicar a request.
Passo a passo prático com CSV no Collection Runner
Este passo a passo foca no uso do Runner com um arquivo CSV para executar múltiplas iterações. A ideia é você ter uma pasta na coleção com requests que usam os campos do CSV. O Runner vai repetir a execução para cada linha.
Passo 1: criar o arquivo CSV com cabeçalho
Crie um arquivo chamado, por exemplo, users-data.csv. A primeira linha deve conter os nomes das colunas (campos). Exemplo:
name,email,password,role,expectedStatus,expectedErrorCode
Ana Silva,ana.silva@example.com,Senha@123,admin,201,
Bruno Lima,bruno.lima@example.com,Senha@123,user,201,
Email Invalido,email-invalido,Senha@123,user,400,INVALID_EMAIL
Sem Senha,sem.senha@example.com,,user,400,PASSWORD_REQUIREDRepare que o CSV pode conter tanto dados de entrada (name, email, password, role) quanto dados esperados para validação (expectedStatus, expectedErrorCode). Essa é uma prática útil: o próprio arquivo de dados descreve o que deve acontecer em cada caso.
Passo 2: parametrizar a request para usar os campos do CSV
Na request de criação, use {{name}}, {{email}}, {{password}} e {{role}} no body. Se você também quiser variar o endpoint ou query params, pode usar placeholders do mesmo jeito. Exemplo de body:
{ "name": "{{name}}", "email": "{{email}}", "password": "{{password}}", "role": "{{role}}" }Passo 3: adicionar testes que leem expectativas do CSV
Em vez de “hardcode” no teste, você pode comparar com o que está no CSV. Isso torna o Runner realmente orientado a dados: cada linha define o resultado esperado. Exemplo de testes:
pm.test("Status conforme esperado", function () { const expected = parseInt(pm.iterationData.get("expectedStatus"), 10); pm.response.to.have.status(expected);});pm.test("Erro esperado quando aplicável", function () { const expectedErrorCode = pm.iterationData.get("expectedErrorCode"); if (expectedErrorCode) { const json = pm.response.json(); pm.expect(json).to.have.property("errorCode"); pm.expect(json.errorCode).to.eql(expectedErrorCode); }});Note o uso de pm.iterationData.get(...). Esse é o acesso direto ao registro atual do arquivo de dados. Embora você também possa usar {{expectedStatus}} em alguns lugares, nos scripts é mais robusto usar pm.iterationData para evitar ambiguidades e facilitar conversões de tipo.
Passo 4: executar no Collection Runner com o CSV
- Abra o Collection Runner e selecione a coleção ou pasta que contém a request.
- Em “Data”, selecione o arquivo
users-data.csv. - Defina o número de iterações automaticamente (o Runner detecta pelo arquivo) ou ajuste se quiser rodar apenas parte do dataset.
- Configure “Delay” se a API tiver rate limit ou se você quiser reduzir carga.
- Inicie a execução e acompanhe a tabela de resultados por iteração.
O Runner vai executar a request uma vez para cada linha do CSV, substituindo os placeholders e avaliando os testes com base nos campos esperados.
Boas práticas com CSV: tipos, valores vazios e consistência
CSV é texto, então tudo chega como string. Quando você precisa comparar números (status esperado, limites, paginação), converta explicitamente com parseInt ou Number. Para valores vazios, o CSV pode gerar string vazia; trate isso com condicionais. Outra boa prática é padronizar nomes de colunas e evitar espaços (use expectedStatus em vez de expected status). Se você editar em planilha, revise se não foram inseridos caracteres invisíveis, aspas extras ou separadores diferentes (vírgula versus ponto e vírgula).
Passo a passo prático com JSON no Collection Runner
Agora vamos ao caso em que você precisa de dados mais complexos, como payloads com objetos aninhados, listas de itens ou variações estruturais. O arquivo JSON do Runner deve ser um array de objetos, em que cada objeto representa uma iteração.
Passo 1: criar o arquivo JSON como array de casos
Crie um arquivo chamado, por exemplo, orders-data.json:
[ { "case": "pedido simples", "customerId": "{{customerId}}", "items": [ { "sku": "SKU-001", "qty": 1 }, { "sku": "SKU-002", "qty": 2 } ], "coupon": null, "expectedStatus": 201 }, { "case": "quantidade invalida", "customerId": "{{customerId}}", "items": [ { "sku": "SKU-001", "qty": 0 } ], "coupon": null, "expectedStatus": 400, "expectedErrorCode": "INVALID_QTY" }]Um detalhe importante: o JSON de dados do Runner não “resolve” automaticamente placeholders como {{customerId}} dentro do próprio arquivo. Em geral, você deve colocar valores literais no arquivo de dados (por exemplo, um customerId real). Se você precisa combinar dados do Runner com valores dinâmicos, faça isso no script (por exemplo, escolher um customerId gerado previamente e injetar no body). Use o campo case para identificar o cenário no relatório do Runner.
Passo 2: montar o body usando dados do iterationData
Para JSON com estruturas aninhadas, muitas vezes é mais simples construir o body via script em vez de tentar usar apenas {{items}}. Uma abordagem prática é: no Pre-request Script, ler o objeto inteiro da iteração e setar o body como JSON. Exemplo:
const data = pm.iterationData.toObject();const payload = { customerId: data.customerId, items: data.items, coupon: data.coupon};pm.variables.set("payload", JSON.stringify(payload));Depois, no body da request (raw JSON), use:
{{payload}}Assim você mantém o arquivo JSON com a estrutura real e evita problemas de serialização de arrays/objetos no template.
Passo 3: testes orientados a dados no JSON
Você pode validar status e códigos de erro com base no arquivo JSON, do mesmo jeito que no CSV:
pm.test("Status conforme esperado", function () { const expected = pm.iterationData.get("expectedStatus"); pm.response.to.have.status(expected);});pm.test("Identificação do caso no log", function () { const caseName = pm.iterationData.get("case"); pm.expect(caseName).to.be.a("string");});pm.test("Erro esperado quando aplicável", function () { const expectedErrorCode = pm.iterationData.get("expectedErrorCode"); if (expectedErrorCode) { const json = pm.response.json(); pm.expect(json.errorCode).to.eql(expectedErrorCode); }});Passo 4: executar no Runner com o JSON
- No Runner, selecione a pasta/coleção.
- Em “Data”, selecione
orders-data.json. - Execute e observe que cada item do array vira uma iteração.
Se você usa o campo case, fica mais fácil localizar rapidamente qual cenário falhou, porque ele aparece nos detalhes da iteração (e você pode também incluí-lo em logs via console.log).
Estratégias de desenho de datasets: positivos, negativos e bordas
O poder do data-driven testing não está apenas em “rodar muitas vezes”, mas em escolher bem os dados. Uma estratégia comum é organizar o dataset em categorias: casos válidos (happy path), casos inválidos (validação de entrada), e casos de borda (limites, tamanhos máximos, strings com caracteres especiais). Em CSV, isso pode ser uma coluna type (por exemplo, happy, negative, edge). Em JSON, pode ser um campo tags como array. Com isso, você consegue filtrar execuções (por exemplo, rodar só negativos) duplicando o arquivo com subconjunto ou ajustando o número de iterações e a ordem dos casos.
Controle de fluxo no Runner com base nos dados
Em cenários data-driven, nem sempre você quer executar todas as requests para todas as linhas. Às vezes, um caso negativo deve parar após validar o erro, sem seguir para requests seguintes da pasta. Uma forma prática é usar um campo no dataset como skipNext ou stopAfterThis e, nos testes, decidir o próximo passo. Exemplo usando postman.setNextRequest:
const stop = pm.iterationData.get("stopAfterThis");if (stop === true || stop === "true") { postman.setNextRequest(null);}Outra variação é pular para uma request específica (por exemplo, ir direto para uma validação) quando um campo indicar isso. Esse tipo de controle é útil quando você tem uma pasta com múltiplas etapas, mas alguns casos precisam de um caminho alternativo.
Reutilizando o mesmo dataset para múltiplas requests
Um padrão comum é ter uma pasta com várias requests que usam os mesmos campos do dataset. Por exemplo, a primeira request cria um recurso com {{name}} e {{email}}, a segunda consulta usando algum identificador retornado, e a terceira tenta atualizar com um valor também vindo do dataset. Mesmo quando o identificador é gerado pela API, o dataset ainda é útil para controlar o restante das entradas e expectativas. Para manter o dataset coeso, inclua no arquivo apenas o que é realmente variável por caso e o que é expectativa por caso; evite colocar dados que são constantes para todos os cenários, pois isso aumenta manutenção.
Diagnóstico de falhas: tornando o Runner “explicável”
Quando você roda dezenas ou centenas de iterações, a principal dificuldade é entender rapidamente por que uma iteração falhou. Algumas práticas ajudam: incluir um campo case (ou id) no dataset; logar esse campo no console; e, quando um teste falhar, incluir mensagens que mencionem o caso e os valores relevantes. Exemplo:
pm.test("Status conforme esperado", function () { const expected = parseInt(pm.iterationData.get("expectedStatus"), 10); const caseName = pm.iterationData.get("case") || pm.iterationData.get("name"); pm.expect(pm.response.code, `Falha no caso: ${caseName}`).to.eql(expected);});Isso reduz o tempo de triagem, porque o erro já aponta qual linha/objeto do dataset precisa ser revisado.
Checklist rápido para evitar problemas comuns
- CSV: confirme que o separador está correto e que o cabeçalho não tem espaços extras.
- Converta tipos no script quando necessário (status esperado, limites numéricos).
- Para JSON com arrays/objetos, prefira montar o payload via script e serializar com
JSON.stringify. - Inclua um identificador de caso no dataset para facilitar rastreio no Runner.
- Coloque expectativas no dataset quando fizer sentido (status, errorCode), para manter testes genéricos e reutilizáveis.
- Se a API tem rate limit, use Delay no Runner e evite datasets enormes sem controle.