Módulo 3: Como escolher o que testar
Partição de equivalência, valor limite, tabela de decisão e transição de estado, as técnicas que transformam "testar" em método
Aquecimento: 2 perguntas do Módulo 2
1. Qual a diferença entre reteste e regressão?
Reteste confirma que aquele bug específico foi corrigido, seguindo os passos
do relatório. Regressão confirma que a correção não quebrou outra coisa que
já funcionava.
2. Por que cobertura de código alta não significa bem testado?
Porque cobertura mede o que foi executado, não o que foi verificado: dá pra
rodar 100% das linhas sem nenhuma asserção sobre o resultado.
O problema: por que não dá pra "testar tudo"
Um campo de idade que aceita de 0 a 120. Quantos testes pra cobrir tudo? 121 valores válidos, mais os negativos, mais os acima de 120, mais texto, mais vazio, mais decimais, mais espaços... Só esse campo já passa de duzentos casos. Agora imagine o formulário inteiro.
A saída não é testar mais rápido, é testar menos, mas os certos. As técnicas abaixo fazem exatamente isso: reduzem centenas de casos a um punhado, com um argumento explícito de por que os descartados não valiam a pena. Esse argumento é o que você apresenta quando alguém pergunta "você testou tudo?".
1. Partição de equivalência
A ideia: valores que o sistema trata do mesmo jeito formam uma classe. Se o código vai pelo mesmo caminho para 37 e para 45, testar os dois não acrescenta nada: um representante por classe basta.
Exemplo. Frete de um pedido, pela regra:
valor < 100,00 → frete R$ 20,00
valor entre 100 e 300 → frete R$ 10,00
valor > 300,00 → frete grátis
As classes válidas são três, e cada uma precisa de um teste só:
| Classe | Representante | Esperado |
|---|---|---|
| abaixo de 100 | R$ 50,00 | frete 20,00 |
| de 100 a 300 | R$ 180,00 | frete 10,00 |
| acima de 300 | R$ 500,00 | frete grátis |
E as classes inválidas, que quase todo iniciante esquece: valor negativo, zero, texto no lugar do número, campo vazio, valor com mais de duas casas decimais. Cada uma é uma classe, cada uma merece um representante. Regra prática: para cada classe válida que você listar, pergunte "qual é o jeito errado de preencher isso?".
2. Análise de valor limite
A ideia: o defeito quase nunca está no meio da faixa: está na
fronteira. É onde alguém escreveu > em vez de
>=, ou esqueceu que o limite é inclusivo. Essa é, de longe, a
técnica com melhor retorno por esforço em teste de software.
Na mesma regra de frete, as fronteiras interessantes são:
| Valor | Por quê | Esperado |
|---|---|---|
| 99,99 | logo abaixo da primeira fronteira | frete 20,00 |
| 100,00 | exatamente na fronteira, o caso que mais quebra | frete 10,00 |
| 100,01 | logo acima | frete 10,00 |
| 299,99 | logo abaixo da segunda fronteira | frete 10,00 |
| 300,00 | na fronteira | frete 10,00 (a regra diz "entre 100 e 300") |
| 300,01 | logo acima | frete grátis |
Repare que a linha do 300,00 obriga você a reler o requisito. "Entre 100 e 300" inclui o 300? E o 100? Se a especificação não responde, você acabou de achar uma ambiguidade, e isso vale mais do que um bug, porque impede que o defeito seja escrito. Leve a pergunta pro refinamento.
Limites que ninguém escreve no requisito
- Zero: quantidade 0, valor 0, lista vazia, carrinho sem itens.
O exercício 6.1 da trilha de SQL existe por causa disso: pedido não
cancelado com
valor_total = 0. - Vazio e nulo: campo em branco, campo nunca preenchido
(
NULL), string só com espaços. Não são a mesma coisa. - Um só: a lista com exatamente 1 item costuma quebrar paginação e concordância de texto ("1 itens").
- Tamanho máximo: o nome com 255 caracteres, e o com 256.
- Datas: 29 de fevereiro, virada de ano, fuso horário, horário de verão.
- Acentos e emoji: "José", "Ação", "🙂" em campo de texto.
Esta lista sozinha já encontra bug em quase qualquer formulário novo.
3. Tabela de decisão
Quando usar: a regra combina várias condições e o resultado depende da combinação, não de cada uma isolada. Aí listar "testei cliente VIP" e "testei cupom" não basta: o defeito mora no cruzamento.
Exemplo. Desconto no checkout:
Cliente VIP → 10% de desconto
Cupom válido → 15% de desconto
Os dois → 20% (não soma os dois)
Nenhum → sem desconto
| Caso | É VIP? | Cupom válido? | Desconto esperado |
|---|---|---|---|
| 1 | não | não | 0% |
| 2 | não | sim | 15% |
| 3 | sim | não | 10% |
| 4 | sim | sim | 20%, não 25% |
Com 2 condições dão 4 casos; com 3, dão 8. A tabela força você a olhar todas as combinações e a perceber as que ninguém especificou. O caso 4 é o clássico: é onde o sistema soma 10 + 15 e dá 25% por engano, e ninguém tinha escrito o que deveria acontecer.
4. Transição de estado
Quando usar: a coisa testada tem estados e só pode andar por certos caminhos. O defeito não está num estado: está numa transição que deveria ser proibida e não é.
Use o pedido do banco deste curso, que tem exatamente esses estados na coluna
status:
novo ──→ pago ──→ enviado ──→ entregue
│ │
└────────┴──→ cancelado
Dois grupos de teste saem direto do desenho:
- Transições válidas: uma por seta. novo→pago, pago→enviado, enviado→entregue, novo→cancelado, pago→cancelado.
- Transições inválidas: o que não tem seta, e é aqui que mora
o dinheiro:
entregue → cancelado: dá pra cancelar o que já foi entregue?novo → entregue: dá pra pular o pagamento?cancelado → pago: dá pra pagar um pedido cancelado?entregue → entregue: entregar duas vezes gera dois e-mails?
Por que isso importa tanto: a interface normalmente esconde os botões proibidos, mas a API não. Trocar o status direto pela API, ou clicar duas vezes rápido, é como esses defeitos aparecem na vida real. Na trilha de Teste de API você faz exatamente isso; na de SQL, você confere o estado resultante no banco.
5. Quando há combinação demais: teste por pares
4 navegadores × 3 sistemas × 3 perfis × 2 idiomas = 72 combinações. Testar todas é inviável; testar uma só é ingênuo.
O teste por pares (pairwise) parte de uma constatação empírica: a grande maioria dos defeitos de combinação aparece na interação de apenas duas variáveis, não de quatro. Então basta montar um conjunto onde cada par de valores apareça ao menos uma vez, o que costuma derrubar as 72 combinações para menos de 15. Existem ferramentas que geram esse conjunto (PICT, AllPairs). Guarde o nome: é uma resposta forte quando perguntarem "e se for muita combinação?".
Juntando tudo: um caso real
História: "Como cliente, quero aplicar um cupom de desconto no carrinho. O cupom tem 8 caracteres, vale para compras a partir de R$ 50,00, e cada cliente pode usar um cupom por pedido."
Passando as quatro técnicas por cima, em ordem:
| Técnica | O que ela faz aparecer |
|---|---|
| Partição | cupom válido; cupom inexistente; cupom expirado; cupom já usado; campo vazio; cupom com 7 e com 9 caracteres |
| Valor limite | carrinho de R$ 49,99 / R$ 50,00 / R$ 50,01; cupom com exatamente 8 caracteres; carrinho vazio (R$ 0) |
| Tabela de decisão | cupom válido × valor suficiente: as 4 combinações, e o que a mensagem deve dizer em cada uma |
| Transição de estado | aplicar cupom → remover → aplicar de novo; aplicar dois cupons seguidos; aplicar cupom e depois esvaziar o carrinho abaixo de R$ 50 |
Repare no último: aplicar o cupom e depois remover itens até o carrinho cair abaixo de R$ 50. Nenhuma leitura ingênua da história produz esse caso; a técnica produziu. É esse o ponto de usar método em vez de intuição.
Olhar de QA
Essas técnicas rendem duas vezes. A primeira é óbvia: bons casos de teste. A segunda é a que te faz notar: elas expõem o que o requisito não diz. Toda vez que você preenche uma linha da tabela e não sabe o que escrever na coluna "esperado", você achou uma ambiguidade. Levar cinco dessas pro refinamento é o trabalho de QA mais barato e mais valioso que existe.
Sua vez
Pegue este requisito e escreva os casos de teste, dizendo qual técnica gerou cada um:
"O campo quantidade de um item no carrinho aceita de 1 a 99 unidades. Acima do estoque disponível, o sistema deve avisar e limitar à quantidade em estoque."
Faça antes de abrir a prova: a questão aberta dela é exatamente esta, com uma resposta modelo pra você comparar.