Testar age=30 quando um campo aceita 18–120 não diz nada sobre o que acontece com 17 ou 18, que é onde os bugs de off-by-one realmente vivem. O particionamento de equivalência agrupa todas as entradas pelo comportamento esperado para que você escolha um representante por grupo em vez de repetir casos equivalentes. A análise de valores de limite mira nos valores em cada borda de partição, onde >= 18 acidentalmente escrito como > 18 passa despercebido.
O que é particionamento de equivalência
O particionamento de equivalência (PE) divide todos os valores de entrada possíveis em grupos chamados partições ou classes de equivalência. Todos os valores do grupo devem se comportar da mesma forma. Se o sistema trata um valor de uma partição corretamente, vai tratar todos eles da mesma forma. Então você só precisa testar um representante de cada partição.
Exemplo: campo de idade em um serviço de streaming
Digamos que o sistema tenha estas regras:
- Usuários devem ter 18 anos ou mais para se cadastrar
- Usuários menores de 13 anos são completamente bloqueados
- Usuários de 13 a 17 anos recebem uma conta "teen" restrita
- Usuários com 18+ recebem uma conta completa
- A idade deve ser um número inteiro entre 1 e 120
Você consegue identificar as partições imediatamente:
| Partição | Faixa | Tipo | Resultado esperado |
|----------|-------|------|-------------------|
| Adulto válido | 18–120 | Válida | Conta completa |
| Teen válido | 13–17 | Válida | Conta teen |
| Menor de 13 | 1–12 | Inválida | Bloqueado |
| Zero ou negativo | ≤ 0 | Inválida | Erro |
| Acima do máximo | > 120 | Inválida | Erro |
| Não inteiro | 17.5, "abc", "" | Inválida | Erro de validação |
Dessas partições, você escolhe um representante de cada. Não precisa testar age=19, age=25, age=50 e age=100. Todos estão na mesma partição. Teste age=30 e você cobriu todos eles.
Seus casos de teste se tornam:
30→ Conta completa (partição adulto válido)15→ Conta teen (partição teen válido)10→ Bloqueado (partição menor de 13)-1→ Erro (partição zero/negativo)200→ Erro (partição acima do máximo)"seventeen"→ Erro de validação (partição não inteiro)
6 testes em vez de potencialmente centenas. E você não perdeu cobertura.
O que é análise de valores de limite
A análise de valores de limite (AVL) se baseia em um fato bem observado: bugs tendem a se concentrar nas bordas das partições, não no meio.
Desenvolvedores escrevem código como if (age >= 18). O bug quase nunca é "funciona com 30, quebra com 31". O bug quase sempre está na fronteira: "funciona com 18, quebra com 17" ou "pretendia usar >= mas escreveu >", então o corte é off-by-one.
A AVL diz: em vez de apenas escolher qualquer representante de cada partição, sempre teste os valores exatamente na fronteira. Isso significa o último valor válido, o primeiro valor válido, e opcionalmente os valores logo fora dos limites.
Valores para testar com AVL
Para qualquer fronteira, você testa:
- Último valor antes da faixa válida (logo abaixo do mínimo)
- Primeiro valor válido (mínimo)
- Último valor válido (máximo)
- Primeiro valor após a faixa válida (logo acima do máximo)
Para o exemplo de idade com fronteiras em 1, 12, 13, 17, 18, 120:
| Fronteira | Valores para testar | Por quê |
|-----------|--------------------|---------|
| Idade mínima válida (1) | 0, 1 | Erros de off-by-one |
| Fronteira teen/bloqueado (13) | 12, 13 | Atribuição correta de partição |
| Fronteira teen/adulto (18) | 17, 18 | O bug de regra de negócio mais comum |
| Idade máxima válida (120) | 120, 121 | Verificação do limite superior |
Seus casos de teste com AVL:
0→ Erro (abaixo do mínimo)1→ Bloqueado (entrada mínima válida)12→ Bloqueado (último valor na partição menor de 13)13→ Conta teen (primeiro valor na partição teen)17→ Conta teen (último valor na partição teen)18→ Conta completa (primeiro valor na partição adulto)120→ Conta completa (último valor na faixa válida)121→ Erro (primeiro valor acima do máximo)
É muito mais completo do que testes aleatórios e bem mais provável de encontrar erros reais de off-by-one.
PE e AVL trabalham juntos
Na prática, você usa as duas técnicas em conjunto:
1. PE primeiro: identifique todas as partições (válidas, inválidas, casos extremos)
2. AVL segundo: para qualquer partição com uma faixa numérica ou ordenada, teste nas fronteiras em vez de (ou além de) um valor aleatório do meio
Aqui está como a cobertura combinada fica para o campo de idade:
| Teste | Entrada | Técnica | Resultado esperado |
|-------|---------|---------|-------------------|
| 1 | -1 | AVL (abaixo do mínimo) | Erro |
| 2 | 0 | AVL (no mínimo absoluto) | Erro |
| 3 | 1 | AVL (mínimo válido) | Bloqueado |
| 4 | 12 | AVL (último bloqueado) | Bloqueado |
| 5 | 13 | AVL (primeiro teen) | Conta teen |
| 6 | 15 | PE (meio da partição teen) | Conta teen |
| 7 | 17 | AVL (último teen) | Conta teen |
| 8 | 18 | AVL (primeiro adulto) | Conta completa |
| 9 | 30 | PE (meio da partição adulto) | Conta completa |
| 10 | 120 | AVL (último válido) | Conta completa |
| 11 | 121 | AVL (primeiro acima do máximo) | Erro |
| 12 | "abc" | PE (partição não inteiro) | Erro de validação |
| 13 | "" | PE (partição vazia) | Erro de validação |
13 casos de teste. Eles vão encontrar praticamente qualquer bug real de validação de idade, incluindo os sutis.
Aplicando a features reais
Tamanho de senha (8–64 caracteres)
Partições:- Vazia → erro
- Curta demais (1–7) → erro
- Válida (8–64) → aceita
- Longa demais (65+) → erro
""(vazia) → erro7 chars→ erro (último valor abaixo do mínimo)8 chars→ aceita (primeiro valor válido)64 chars→ aceita (último valor válido)65 chars→ erro (primeiro acima do máximo)
20 chars → aceita
São 6 testes cobrindo toda a faixa válida/inválida.
Campo de email
Aqui só faz sentido o particionamento (sem fronteiras numéricas limpas):
Partições:- Vazio → erro
- Formato válido (nome@dominio.com) → aceito
- Sem @ → erro
- Sem domínio → erro
- Múltiplos @ → erro
- Caracteres internacionais → depende da spec do sistema
Teste um valor de cada partição. Não teste 50 formatos de email válidos — todos vão para a partição "formato válido".
Dropdown com valores fixos
Se um campo aceita apenas valores específicos (Pequeno/Médio/Grande), não há fronteiras para analisar com AVL. O PE é suficiente:
- Valor válido (Médio) → aceito
- Valor inválido fora da lista (Extra Grande) → erro
- Vazio → erro
Erros comuns para evitar
Testar muitos valores da mesma partição
Se você testa idades 20, 25, 30, 35 e 45, escreveu 5 testes que vivem todos na mesma partição. Todos vão passar ou falhar juntos. Você não ganhou nada com esses 4 testes extras.
Correção: escolha um representante por partição e teste nas fronteiras.Esquecer as partições inválidas
Iniciantes frequentemente pensam apenas na entrada válida. Os bugs reais moram no que acontece com entrada inválida: números negativos, strings vazias, valores levemente acima do máximo.
Correção: liste as partições inválidas explicitamente. É frequentemente onde os bugs interessantes se escondem.Perder partições não óbvias
Para um campo de "código de desconto":
- Partições comuns: código válido, código inválido, vazio
- Partições fáceis de perder: código expirado, código já usado, código para outro produto, código com maiúsculas erradas (é case-sensitive?)
Aplicar AVL a dados não ordenados
A AVL só faz sentido para dados com ordenação natural: números, datas, comprimentos. Você não consegue aplicar AVL a uma lista de códigos de país ou a um conjunto de valores enum. Use PE nesses casos.
Um processo prático
Quando você encontra qualquer campo de entrada ou regra de negócio, siga estes passos:
Passo 1: Que valores este campo aceita? Quais são as regras? Passo 2: Liste todas as partições — válidas e inválidas. Escreva o comportamento esperado para cada uma. Passo 3: Para qualquer partição com faixa numérica ou ordenada, identifique as fronteiras. Liste os valores último-inválido/primeiro-válido e último-válido/primeiro-inválido. Passo 4: Escolha um representante de cada partição sem fronteira (para o meio das faixas válidas). Adicione os valores de fronteira. Passo 5: Escreva seus casos de teste, um por valor identificado.Isso leva 5–10 minutos por feature e produz um conjunto de testes eficiente e justificável que você consegue explicar para qualquer pessoa.
Por que isso importa para automação de testes
Quando você está escrevendo testes Playwright, essas técnicas ajudam a decidir o que parametrizar. Em vez de escrever 20 testes quase idênticos que só mudam o valor de entrada, você escreve um teste parametrizado com os 6–8 valores que PE e AVL identificaram:
const AGE_CASES = [
{ input: '-1', expect: 'error', label: 'abaixo do mínimo' },
{ input: '1', expect: 'blocked', label: 'mínimo válido' },
{ input: '12', expect: 'blocked', label: 'último bloqueado' },
{ input: '13', expect: 'teen account', label: 'primeiro teen' },
{ input: '17', expect: 'teen account', label: 'último teen' },
{ input: '18', expect: 'full account', label: 'primeiro adulto' },
{ input: '120', expect: 'full account', label: 'último válido' },
{ input: '121', expect: 'error', label: 'acima do máximo' },
];
for (const { input, expect, label } of AGE_CASES) {
test(`age ${label}: ${expect}`, async ({ page }) => {
await page.fill('[data-testid="age-input"]', input);
await page.click('[data-testid="submit"]');
await expect(page.locator('[data-testid="result"]')).toContainText(expect);
});
}Limpo, legível, e cada teste tem uma razão clara de existir.
Conclusão
- Particionamento de equivalência agrupa entradas pelo comportamento esperado: teste um valor por grupo
- Análise de valores de limite mira nas bordas entre grupos, onde vivem os bugs de off-by-one
- Use PE para identificar partições, AVL para escolher os valores exatos a testar
- Sempre inclua partições inválidas: os testes de "o que acontece com entrada ruim" encontram bugs reais
- O objetivo é mínimo de testes, máxima cobertura — não testar tudo, mas testar as coisas certas
Essas duas técnicas são a base do design estruturado de testes. Quando você as internaliza, começa a aplicá-las instintivamente toda vez que olha para uma feature nova, mesmo antes de abrir o editor de testes.
→ Veja também: Técnicas de Design de Casos de Teste: EP, BVA, Tabelas de Decisão, Transição de Estados | 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