SkillsTecnológicas
Menu
Conteúdo da trilha

Como criar casos de teste

Transforme requisitos em casos de teste claros, escolha dados representativos e cubra decisões sem acumular exemplos repetidos.

Conteúdo 48 de 52

Uma regra desenhada a lápis separa peças de madeira em famílias e seleciona um representante de cada grupo para verificação

Um caso de teste é uma pergunta verificável feita ao algoritmo

Criar um caso de teste não é escolher um número qualquer e observar o que acontece. É definir uma situação concreta, executar uma ação e comparar o resultado obtido com uma expectativa derivada das regras.

Um caso útil responde:

  • qual comportamento está sendo verificado?
  • quais condições precisam existir antes da execução?
  • quais entradas serão usadas?
  • qual ação será executada?
  • qual resultado deve ser observado?
  • de qual regra veio essa expectativa?

Cada caso é uma pergunta específica. A suíte de testes é o conjunto de perguntas que cobre comportamentos diferentes sem acumular repetições sem propósito.

A aula de teste de mesa e rastreamento de variáveis mostra como acompanhar uma execução. Aqui, o foco muda: antes de executar, vamos decidir quais execuções merecem existir.

Comece pelo contrato, não pela implementação

O contrato descreve o que o algoritmo deve fazer. Ele pode estar em requisitos, critérios de aceitação, exemplos aprovados ou regras de negócio. Os casos devem nascer dessa fonte, não dos caminhos que você acabou de ler no código.

Usar a implementação como única fonte cria um risco circular: se uma condição foi esquecida no código, ela também pode ser esquecida nos testes.

Considere este contrato de frete:

  1. retirada na loja custa R$ 0;
  2. na entrega, cliente premium recebe frete grátis a partir de R$ 120;
  3. qualquer cliente recebe frete grátis a partir de R$ 200;
  4. nas demais entregas, o frete custa R$ 20;
  5. o subtotal precisa ser um valor válido maior ou igual a zero.

O algoritmo recebe:

subtotal
cliente_premium
retirada_na_loja

e devolve o valor do frete ou informa que a entrada foi rejeitada.

Antes de pensar nos dados, numere as regras. Essa identificação permitirá provar depois que cada comportamento tem pelo menos um caso associado.

Converta regras em condições observáveis

Uma frase pode esconder várias condições. “Cliente premium recebe frete grátis a partir de R$ 120” envolve:

  • modalidade igual a entrega;
  • cliente premium igual a verdadeiro;
  • subtotal maior ou igual a 120;
  • resultado esperado igual a 0.

Transforme cada regra em uma relação entrada–resultado:

RegraCondição testávelResultado esperado
R1retirada na loja0
R2entrega, premium e subtotal ≥ 1200
R3entrega e subtotal ≥ 2000
R4entrega sem atender R2 nem R320
R5subtotal fora do contratorejeição

Se não for possível escrever um resultado inequívoco, o problema ainda está no contrato. Por exemplo: retirada com subtotal inválido deve ser rejeitada antes de calcular o frete ou a retirada prevalece? O teste não resolve essa ambiguidade; ele a revela para que a regra seja decidida.

Uma regra origina preparação, entrada e ação que convergem para a comparação entre resultado esperado e observado
O resultado esperado vem do contrato e precisa existir antes da observação do resultado real.

Escreva o resultado esperado antes de executar

O resultado esperado funciona como oráculo de teste: é a base usada para decidir se o comportamento observado está correto.

Para subtotal 150, cliente premium e entrega, a expectativa é frete 0 por R2. Escreva isso antes de rodar o algoritmo:

dado subtotal 150
e cliente premium
e modalidade entrega
quando o frete for calculado
então o resultado será 0 por causa da regra R2

Se você executar primeiro e anotar o valor devolvido como expectativa, um erro pode validar a si mesmo. Calcule a resposta pelo contrato, por um exemplo aprovado ou por um método independente.

Uma expectativa também precisa ser observável. “Funcionar corretamente”, “responder rápido” ou “mostrar mensagem adequada” não define uma comparação. Prefira “devolver 0”, “rejeitar sem calcular o frete” ou “manter o saldo em 50”.

Divida as entradas por comportamento equivalente

Testar todos os subtotais possíveis é inviável. A partição de equivalência agrupa valores que, conforme o contrato, devem produzir o mesmo tipo de comportamento.

Para cliente regular com entrega, o subtotal possui duas regiões principais:

  • de 0 até antes de 200: frete 20;
  • a partir de 200: frete 0.

Os valores 40, 80 e 150 pertencem à mesma região de comportamento. Se o objetivo é verificar somente a regra de frete regular, repetir dezenas de valores internos acrescenta menos informação do que testar outra região ainda descoberta.

Para cliente premium, a divisão muda:

  • de 0 até antes de 120: frete 20;
  • a partir de 120: frete 0.

As partições dependem da regra, não apenas do tipo da variável. O mesmo subtotal 150 pertence à região paga para cliente regular e à região gratuita para cliente premium.

Escolha inicialmente um representante claro de cada região. Depois acrescente valores próximos das transições e combinações de maior risco.

Trate cada limite como uma mudança de comportamento

Um limite é o ponto em que uma pequena mudança de entrada pode selecionar outra regra. No exemplo, 120 e 200 são transições.

Um conjunto inicial pode incluir:

ClienteSubtotalEsperadoMotivo
premium119,9920imediatamente antes de R2
premium1200início de R2
regular199,9920imediatamente antes de R3
regular2000início de R3

Esses pares verificam se “a partir de” foi traduzido como >=, e não como >. O conteúdo seguinte aprofundará limites, extremos e entradas inválidas; por enquanto, use o limite para representar a transição entre duas regras já conhecidas.

Duas faixas de subtotal mostram que o frete premium muda em cento e vinte e o frete regular muda em duzentos, com representantes de cada região
As mesmas entradas podem pertencer a comportamentos diferentes quando outra condição, como o tipo de cliente, muda.

Use uma tabela de decisão quando as condições se combinam

Escolher um valor por variável de forma isolada não cobre necessariamente as combinações relevantes. Retirada, categoria do cliente e subtotal interagem.

Monte uma tabela com as decisões que alteram a saída:

Caso lógicoRetirada?Premium?Faixa do subtotalFrete
C1simqualquerválida0
C2nãosimabaixo de 12020
C3nãosim120 ou mais0
C4nãonãoabaixo de 20020
C5nãonão200 ou mais0

“Qualquer” não significa que a entrada desapareceu. Significa que, para aquela regra, mudar a categoria do cliente não altera a resposta. Ainda assim, pode valer criar mais de um caso se houver risco de a implementação consultar indevidamente essa condição.

A tabela também revela redundâncias. Um caso “regular, entrega, subtotal 80” e outro “regular, entrega, subtotal 100” exercitam o mesmo comportamento lógico C4. Mantenha ambos somente se existir uma razão adicional, como uma transformação específica ou um defeito anterior.

Transforme cada linha lógica em um caso concreto

Um caso documentado pode usar esta estrutura:

CampoConteúdo
IDFRETE-03
objetivoverificar gratuidade premium no limite
regraR2
pré-condiçõesserviço de entrega disponível
entradassubtotal 120, premium sim, retirada não
açãocalcular frete
resultado esperado0

O ID serve para rastrear, não para explicar. O objetivo ou nome deve dizer qual comportamento está sob teste.

Ao automatizar, a mesma organização pode aparecer como preparar, agir e verificar — frequentemente chamada Arrange–Act–Assert:

// preparar
const pedido = { subtotal: 120, premium: true, retirada: false };

// agir
const frete = calcularFrete(pedido);

// verificar
expect(frete).toBe(0);

Mantenha uma ação principal. Se um caso calcula, altera o pedido, calcula novamente e faz várias verificações, uma falha intermediária pode esconder comportamentos posteriores. Separe os cenários ou use casos parametrizados quando a estrutura for a mesma e apenas os dados variarem.

Dê nomes que descrevam condição e consequência

Compare:

testeFrete1

com:

entregaPremium_ComSubtotalNoLimite_DevolveFreteZero

O segundo nome comunica:

  • contexto: entrega premium;
  • situação: subtotal no limite;
  • consequência: frete zero.

Um relatório de falha com nomes descritivos já indica qual regra deixou de ser satisfeita. Evite nomes baseados somente no número do caso ou na função chamada.

Mantenha os casos independentes e repetíveis

Um caso deve produzir o mesmo resultado quando executado sozinho ou junto da suíte, desde que o ambiente seja o mesmo.

Evite que um teste dependa do saldo, arquivo ou variável deixada pelo teste anterior. Prepare o estado necessário no próprio caso e restaure recursos modificados quando aplicável.

Controle fontes de variação:

  • horário atual;
  • números aleatórios;
  • ordem de itens quando ela não é garantida;
  • respostas externas;
  • dados compartilhados;
  • configurações diferentes entre ambientes.

Repetibilidade não significa ignorar variações reais. Significa tornar explícito qual variação faz parte do caso e qual precisa ser controlada para que a comparação tenha sentido.

Remova repetição somente depois de mapear a cobertura

Um conjunto menor é valioso quando preserva os comportamentos importantes. Não elimine casos apenas porque as entradas “parecem parecidas”. Compare o que cada um cobre.

Monte uma matriz de rastreabilidade:

RegraFRETE-01FRETE-02FRETE-03FRETE-04FRETE-05
R1 retirada grátis
R2 premium ≥ 120
R3 qualquer cliente ≥ 200
R4 demais entregas = 20

FRETE-02 pode representar premium abaixo de 120; FRETE-04, cliente regular abaixo de 200. Ambos esperam 20, mas não são repetidos: exercitam condições diferentes.

Matriz liga quatro regras de frete a cinco casos e mostra que cada regra possui cobertura sem considerar iguais os dois casos de frete pago
Resultados iguais não tornam dois casos equivalentes quando eles verificam regras ou caminhos diferentes.

A matriz encontra dois problemas:

  • lacuna: uma regra sem nenhum caso;
  • repetição aparente: vários casos cobrem exatamente as mesmas condições sem outra justificativa.

Cobertura não garante ausência de defeitos. Ela demonstra quais perguntas foram feitas; não prova que todas as perguntas possíveis foram contempladas.

Execute o caso sem alterar a expectativa

Durante a execução, registre separadamente:

esperado: 0
observado: 20
resultado: falhou

Não troque o esperado para 20 apenas porque o algoritmo devolveu esse valor. Uma divergência pode indicar:

  1. defeito no algoritmo;
  2. expectativa calculada incorretamente;
  3. requisito ambíguo ou contraditório;
  4. preparação diferente da documentada;
  5. observação feita no ponto errado.

Releia a regra e reproduza o caso. Se a expectativa estiver errada, corrija o caso e registre a razão. Se o algoritmo estiver errado, use o processo de identificação de erros para localizar a primeira divergência.

Faça a suíte crescer por informação, não por quantidade

Acrescente um caso quando ele introduzir pelo menos uma informação relevante:

  • cobre uma regra ainda descoberta;
  • atravessa outro ramo;
  • representa outra partição de comportamento;
  • verifica uma transição;
  • combina condições que podem interagir;
  • reproduz um defeito real e impede sua volta;
  • cobre um risco com impacto importante.

Evite métricas vazias como “precisamos de cem casos”. Dez casos derivados de regras claras podem ser mais úteis que centenas de entradas aleatórias que percorrem o mesmo caminho.

Quando o contrato mudar, atualize primeiro o inventário de regras e a matriz. Assim você identifica quais casos precisam mudar, quais continuam válidos e quais deixaram de ter justificativa.

Pratique com classificação de temperatura

Use este contrato:

abaixo de 18: frio
de 18 até antes de 26: confortável
a partir de 26: quente

Crie uma suíte seguindo estas etapas:

  1. numere as três regras;
  2. defina as partições de comportamento;
  3. escolha um representante interno de cada partição;
  4. acrescente pares que verifiquem as transições em 18 e 26;
  5. escreva esperado antes de executar;
  6. dê um nome descritivo a cada caso;
  7. construa a matriz regra × caso;
  8. remova apenas casos que não acrescentem regra, transição ou risco;
  9. execute cada caso com um teste de mesa;
  10. registre esperado, observado e resultado.

A suíte está bem formada quando outra pessoa consegue explicar por que cada caso existe e qual ausência surgiria se ele fosse removido.

O que você deve guardar

Casos de teste eficazes nascem do contrato. Primeiro transforme regras em condições e resultados observáveis; depois divida entradas por comportamento, examine transições e combine decisões que alteram a saída.

Cada caso precisa ter objetivo, preparação, entradas, ação, expectativa e ligação com uma regra. A matriz de rastreabilidade mostra lacunas e evita confundir quantidade com cobertura. Escreva o esperado antes de executar e preserve a independência entre casos.

O próximo passo é aprender a testar casos extremos e entradas inválidas, distinguindo valores permitidos nas bordas de violações do contrato.

Referências