Teste positivo e negativo no desenvolvimento de software
Quando comecei a trabalhar com QA há alguns anos, meu time achava que fazer teste positivo e negativo era uma formalidade. A gente escreveu testes unitários, passou tudo verde, e ainda assim um bug simples de input escapou para produção. Foi um dia em que um campo numérico aceitava caracteres vazios e quebrava a interface inteira. Desde então, nunca mais encaro isso como checklist. O teste positivo é straightforward: você alimenta o sistema com dados que estão dentro do esperado e verifica se ele responde corretamente. O negativo, bem, é o oposto. Você joga coisas que o sistema não deveria aceitar — strings onde deveria vir número, valores nulos, payloads truncados, headers faltando — e espera que ele falhe de forma previsível, não catastrófica.
Como eu implemento hoje
Não confio em teste manual isolado. Se eu vou rodar teste positivo e negativo, pelo menos na minha stack atual, eu embuto ambos num único suite de parametrização. No Python, uso pytest.mark.parametrize com um dict que agrupa cases positivos e negativos lado a lado. Fica assim:
👉 Clique no botão abaixo para saber mais sobre o assunto!
@pytest.mark.parametrize("input,expected_status", [
("valid_id_123", 200),
("", 400),
("abc", 400),
(None, 400),
])
def test_endpoint(input, expected_status):
...
Isso evita que o positivo e o negativo virem dois buckets separados que depois ninguém mantém em sincronia. E olha, eu já vi time deixar os casos negativos num arquivo à parte que ninguém consultava há três meses.
Pegadinha que eu levei
Tem um cenário que eu considero clássico e que quase todo mundo subestima: validar o tipo, mas não validar o range. Eu estava debugando uma API que aceitava idade como string numérica. O teste positivo passava com "25". O teste negativo falhava com letras. Mas um usuário mandou "-1" e o sistema deixou passar porque o parser só checava se era inteiro, não se fazia sentido no domínio. Isso gerou um registro de paciente com idade negativa no banco. A correção foi adicionar validação de constraints pós-conversão de tipo, coisa que o padrão de "teste positivo e negativo" de formato não cobre sozinho.
Quando esseApproach não funciona
O teste positivo e negativo puro tem limite. Se você precisa cobrir estados complexos — sessões expiradas, tokens roubados, concurrency de escrita —, ele sozinho não chega. Nesse caso, eu complemento com testes de estado (stateful testing) e fuzzing leve, especialmente em interfaces expostas. E cuidado com o viés de quem escreve o teste: você tende a testar o que conhece, não o que o usuário vai mandar de forma estranha. Em resumo, manter cases positivos e negativos juntos, com validação de domínio, e revisitar periodicamente os cenários que mais quebrou em produção.