Caixa preta: comece pelo contrato
Em caixa preta, o teste é desenhado a partir de requisitos, entradas e resultados, sem depender de como o código está organizado. Uma chamada para criar pedido pode ser verificada pelo status HTTP, representação devolvida e efeito observável. A implementação pode ser refatorada sem exigir mudança no teste, desde que o contrato continue igual.
Isso não significa desconhecer o sistema inteiro ou testar apenas pela interface. Um teste automatizado de função ou endpoint pode ser caixa preta em relação ao componente testado. Sua força depende da seleção de entradas e resultados, e não de cobrir todo o espaço possível.
Particionamento e valores de fronteira
Divida entradas em classes que deveriam se comportar da mesma forma e escolha representantes. Para uma quantidade aceita de 1 a 100, classes possíveis incluem abaixo do mínimo, faixa permitida e acima do máximo. Teste também os limites 0, 1, 100 e 101, pois erros de comparação aparecem frequentemente nas fronteiras.
Essa técnica reduz combinações sem ignorar casos relevantes. Se várias entradas interagem, escolha combinações guiadas pelo risco em vez de testar cegamente cada permutação.
Caixa branca: use a estrutura para procurar lacunas
Caixa branca considera código, decisões e caminhos internos para planejar verificações. Pode revelar ramos não exercitados, caminhos de erro, condições compostas ou loops que não aparecem em exemplos funcionais comuns. Cobertura de instruções e branches ajuda a localizar áreas não executadas, mas cobertura alta não prova que as asserções verificam resultados corretos.
Não exija testes separados para cada linha por princípio. Use conhecimento da estrutura para identificar riscos e, quando possível, expresse a verificação pelo comportamento público para evitar acoplamento desnecessário à implementação.
Caixa cinza e contexto operacional
Caixa cinza combina uma visão externa com conhecimento parcial do desenho, dados ou infraestrutura. Por exemplo, um teste de integração pode saber que uma consulta usa um índice ou que mensagens passam por um consumer group, sem testar cada detalhe interno do banco ou broker. Essa informação ajuda a escolher cenários de concorrência, timeout, repetição e recuperação.
Conhecer internals também pode enviesar testes para o desenho atual. Registre qual risco a informação interna ajuda a validar e mantenha o foco no efeito importante para o sistema.
Propriedades, mutações e testes exploratórios
Teste baseado em propriedades verifica uma regra ampla para muitos dados gerados, como uma ordenação que deve preservar quantidade e deixar a sequência ordenada. É útil para parsers, conversões e algoritmos com invariantes claros; exige geradores e mensagens de falha que permitam reproduzir o caso.
Mutation testing altera temporariamente o código para verificar se os testes detectam a mudança, oferecendo uma medida adicional de sensibilidade. Testes exploratórios, por sua vez, usam investigação humana e observações para encontrar comportamentos não previstos. Essas abordagens ampliam a análise, mas não substituem critérios claros nem validação de contratos.
Combine perspectivas sem duplicar o mesmo teste
Comece por requisitos e exemplos de caixa preta, use a estrutura interna para descobrir limites esquecidos e acrescente contexto de caixa cinza nos pontos de integração e falha. Uma regra de domínio costuma caber num teste unitário; colaboração sobre exemplos se relaciona ao BDD; uma API integrada pode ser coberta por testes funcionais.