Testar um campo de idade que aceita 18 a 65 com valores aleatórios como 25, 42 e 60 não diz nada que o primeiro valor já não dissesse. Os bugs se escondem nas bordas: 17, 18, 65 e 66, os valores exatos onde um erro de off-by-one na condição aparece.

Particionamento de equivalência: pare de testar a mesma coisa duas vezes

A ideia central é simples: se dois inputs produzem o mesmo comportamento, você só precisa testar um deles. Você divide o espaço total de inputs em grupos (chamados de partições ou classes de equivalência) onde todo valor em um grupo se comporta da mesma forma. Depois testa um valor representativo de cada grupo.

Considere um formulário de registro com um campo de idade. O requisito diz que os usuários devem ter entre 18 e 65 anos. Você poderia testar cada inteiro de 0 a 120, mas isso são 121 casos de teste. O particionamento de equivalência diz que há apenas quatro grupos que importam:

| Partição | Faixa | Valor de exemplo |

|----------|-------|-----------------|

| Válida | 18 a 65 | 35 |

| Jovem demais (inválida) | Abaixo de 18 | 10 |

| Velho demais (inválida) | Acima de 65 | 80 |

| Tipo errado (inválida) | Não numérico | "vinte" |

Quatro casos de teste em vez de 121. A lógica é que se 35 passa e 36 também passa, testar 36 não fornece informação adicional. Se 10 falha corretamente, 11 também vai falhar.

O particionamento de equivalência se aplica a qualquer input com uma faixa válida definida. Exemplos: campos de texto com limites de comprimento, dropdowns com valores permitidos, uploads de arquivo com restrições de tamanho, parâmetros de API com valores enumerados.

Análise de valor de contorno: onde os bugs realmente se escondem

Desenvolvedores cometem erros nas bordas. Um erro de off-by-one parece com if (age > 18) em vez de if (age >= 18). O particionamento de equivalência encontra as partições; a análise de valor de contorno (BVA) testa as paredes entre elas.

Para o mesmo campo de idade 18 a 65, BVA produz esses casos de teste:

| Valor | Fronteira da partição | Resultado esperado |

|-------|----------------------|-------------------|

| 17 | Justo abaixo do limite inferior | Rejeitado |

| 18 | Limite inferior | Aceito |

| 19 | Justo acima do limite inferior | Aceito |

| 64 | Justo abaixo do limite superior | Aceito |

| 65 | Limite superior | Aceito |

| 66 | Justo acima do limite superior | Rejeitado |

Seis casos de teste que cobrem ambas as fronteiras dos dois lados. Combine com o particionamento de equivalência, que cobre o meio e o tipo errado. Você terá uma suite completa para esse campo com cerca de 8 a 10 casos de teste no total.

BVA funciona onde quer que haja uma fronteira: limites de caracteres em campos de texto, tamanhos de arquivo, quantidades mínimas de pedido, intervalos de datas, paginação, rate limits de API. O padrão é sempre o mesmo: teste o valor na fronteira, um abaixo e um acima.

Quando você encontra um bug com BVA, ele quase sempre está na fronteira exata. Um campo de idade que rejeita 65 mas aceita 64 e 66 revela um erro de off-by-one. Nomeie isso especificamente no bug report. "Falha de condição de fronteira no limite superior" ajuda o desenvolvedor a encontrá-lo mais rápido.

Tabelas de decisão: tornando a lógica de negócio visível

Algumas features não têm um único input com uma faixa; têm múltiplas condições que se combinam para produzir resultados diferentes. Descontos no checkout, regras de acesso a conteúdo, upgrades de assinatura, preferências de notificação: todos têm lógica combinatória complexa difícil de raciocinar apenas com os requisitos.

Tabelas de decisão tornam essa lógica explícita. Cada coluna é um caso de teste. Cada linha é uma condição ou um resultado.

Tome uma feature de desconto: usuários recebem desconto se têm cartão fidelidade ou se a compra total é acima de R$100. As combinações ficam assim:

| | Caso 1 | Caso 2 | Caso 3 | Caso 4 |

|---|---|---|---|---|

| Tem cartão fidelidade | Não | Sim | Não | Sim |

| Compra > R$100 | Não | Não | Sim | Sim |

| Recebe desconto | Não | Sim | Sim | Sim |

Essa é uma regra OR, então três dos quatro casos resultam em desconto. Quatro casos de teste, um por coluna. Se a regra fosse AND (precisa ter cartão fidelidade E compra acima de R$100), apenas o Caso 4 se qualificaria. A tabela mostraria isso imediatamente, e você saberia que precisa testar as quatro combinações para confirmar a lógica.

Tabelas de decisão brilham quando os requisitos contêm palavras como "se," "quando," "a menos que," "exceto quando," "mas somente se." Essas palavras sinalizam que a lógica condicional precisa ser mapeada. A tabela força você a enumerar cada combinação, o que frequentemente revela casos que os requisitos não especificaram. O que acontece se o usuário não tem cartão fidelidade e o pedido é exatamente R$100? A tabela torna essa ambiguidade visível antes do desenvolvimento, quando é barato resolver.

Para uma feature com três condições binárias, você tem 2³ = 8 combinações. Para quatro condições, 16. Tabelas de decisão nem sempre exigem testar todas as combinações (algumas podem ser impossíveis ou irrelevantes), mas ajudam a ver o espaço completo antes de decidir quais cortar.

Teste de transição de estados: features que lembram onde estiveram

Algumas features não apenas respondem a inputs; elas mantêm estado, e as ações válidas dependem do estado em que estão atualmente. Fluxos de autenticação, workflows de status de pedido, gerenciamento de assinatura, ciclo de vida de conta de usuário: todos se comportam de forma diferente dependendo do que já aconteceu.

O teste de transição de estados mapeia os estados possíveis, os eventos que causam transições e os comportamentos esperados em cada transição.

Tome o gerenciamento de conta de usuário. Uma conta pode estar em um dos três estados: Ativa, Bloqueada e Suspensa. As transições entre eles são acionadas por eventos específicos:

| Estado atual | Evento | Próximo estado | Comportamento esperado |

|--------------|--------|----------------|----------------------|

| Ativa | 5 logins falhos | Bloqueada | Mostrar mensagem de bloqueio, bloquear tentativas |

| Ativa | Admin suspende | Suspensa | Mostrar aviso de suspensão, encerrar sessões ativas |

| Bloqueada | 15 minutos passam | Ativa | Permitir tentativas de login novamente |

| Bloqueada | Admin desbloqueia | Ativa | Acesso restaurado imediatamente |

| Suspensa | Admin reintegra | Ativa | Conta restaurada, usuário notificado |

| Suspensa | 5 logins falhos | Suspensa | Permanecer suspensa (sem transição) |

Dessa tabela, você deriva dois tipos de casos de teste. O primeiro verifica transições válidas: confirmar que "Ativa + 5 logins falhos → Bloqueada" funciona conforme documentado. O segundo verifica transições inválidas: confirmar que uma conta Suspensa não pode transicionar para Bloqueada ao tentar login, e que o sistema trata esse caso extremo corretamente.

A tabela também revela lacunas. O que acontece se uma conta Bloqueada recebe um evento "Admin suspende"? O requisito pode não dizer. Diagramas de transição de estados tornam essas lacunas visíveis como células vazias.

O teste de transição de estados é especialmente valioso para workflows que QAs juniores tendem a sub-testar: o que acontece se você aciona uma ação em um objeto que já está no estado "errado"? E se você executa o passo 3 antes do passo 2? As transições válidas são óbvias; as inválidas são onde os bugs vivem.

Teste combinatório: quando as combinações explodem

Algumas features têm tantas variáveis de input que uma tabela de decisão completa é impraticável. Um filtro de busca com 5 opções, cada uma com 3 a 4 valores possíveis, produz milhares de combinações. Você não consegue testar todas.

O teste por pares (também chamado de all-pairs testing) é a resposta prática. Pesquisas mostram que a maioria dos bugs é causada por interações entre duas variáveis, não três ou mais. O teste por pares garante que cada par de valores de variáveis diferentes apareça em pelo menos um caso de teste.

Imagine testar um formulário de reserva de viagem com estas opções:

  • Destino: Europa, Ásia, Américas (3 valores)
  • Tipo de viagem: Só ida, Ida e volta (2 valores)
  • Classe: Econômica, Executiva, Primeira (3 valores)
  • Mês de partida: Verão, Inverno (2 valores)

Teste fatorial completo: 3 × 2 × 3 × 2 = 36 combinações. O teste por pares cobre todos os pares em aproximadamente 9 casos de teste.

Você não constrói conjuntos de teste por pares manualmente. Ferramentas fazem isso por você. PICT (Pairwise Independent Combinatorial Testing) é uma ferramenta gratuita de linha de comando da Microsoft. AllPairs é outra. Você define os parâmetros e valores, executa a ferramenta e recebe um conjunto mínimo de testes.

O teste por pares é a escolha certa quando você tem 4 ou mais variáveis com vários valores cada. Use-o quando a cobertura completa não é viável e você precisa de um método defensável para reduzir o escopo sem adivinhar quais combinações pular.

Qual técnica usar: um guia de decisão

As técnicas não são mutuamente exclusivas. A maioria das features reais usa mais de uma. Como escolher:

Particionamento de equivalência se encaixa em qualquer input com uma faixa válida definida: campos de idade, faixas de preço, limites de comprimento de caracteres, valores válidos enumerados. Use-o para organizar inputs antes de escrever casos de teste individuais. Análise de valor de contorno combina com particionamento de equivalência para as mesmas situações. Toda vez que o particionamento de equivalência identifica uma fronteira, adicione casos de teste BVA em torno dela. Sempre. Tabelas de decisão se encaixam em features com múltiplas condições independentes que se combinam para produzir resultados diferentes. Se os requisitos usam lógica "se/e/ou/a menos que," construa uma tabela de decisão antes de escrever casos de teste. Teste de transição de estados se encaixa em features com um ciclo de vida ou workflow definido. Se um objeto (usuário, pedido, ticket, assinatura) pode estar em estados diferentes e transicionar entre eles, mapeie os estados primeiro, depois derive os casos de teste. Teste por pares se encaixa em testes de configuração e features com muitas variáveis independentes. Se você tem mais de 3 a 4 variáveis e a cobertura completa é impraticável, use uma ferramenta de pares.

Para um campo de input simples sem estado e sem lógica de múltiplas condições, particionamento de equivalência mais BVA é tudo que você precisa. Para um fluxo de checkout com descontos, níveis de usuário e múltiplos métodos de pagamento, tabelas de decisão combinadas com teste de estados cobrem mais do que intuição pura.

Como aplicar isso na segunda de manhã

Você não precisa reformular todo o processo de testes de uma vez. Pegue uma feature que você está testando esta semana e aplique uma técnica.

Se você está testando um campo de input com restrições de mínimo e máximo: escreva as partições de equivalência no papel antes de abrir a aplicação. Identifique as fronteiras. Escreva os casos de teste BVA. Você terá um teste completo do campo em cinco minutos em vez de digitar valores aleatórios por vinte.

Para uma regra de negócio com múltiplas condições (lógica de desconto, controle de acesso, gatilhos de notificação): construa a tabela de decisão antes de escrever casos de teste. Cada coluna se torna um caso de teste. Verifique se alguma combinação é ambígua nos requisitos e pergunte antes de testar.

Para um workflow com mudanças de status (gestão de pedidos, ciclo de vida do usuário, roteamento de ticket de suporte): desenhe o diagrama de estados, mesmo que seja rascunho. Liste as transições válidas e os eventos que as acionam. Depois escreva dois casos de teste por transição: um que confirma que funciona, um que tenta uma transição inválida de um estado similar.

O objetivo não é aplicar todas as técnicas a todas as features. É parar de depender de memória e intuição para decisões que têm respostas corretas e sistemáticas. As técnicas transformam "o que eu deveria testar?" de uma pergunta que você responde diferente cada vez num processo que você pode repetir, defender e ensinar.

→ Veja também: Como Escrever um Caso de Teste: Formato, Exemplos e Erros Comuns | Testes Baseados em Risco: Priorizando o que Testar Quando Não é Possível Testar Tudo | Particionamento de Equivalência e Análise de Valor Limite: Guia Prático | Caso de Teste vs Cenário de Teste: Diferença e Quando Usar Cada Um