As declarações são úteis para informar sobre o estado interno do programa . Por exemplo, que suas estruturas de dados têm um estado válido, por exemplo, que uma Time
estrutura de dados não retém o valor de 25:61:61
. As condições verificadas por afirmações são:
Condições prévias, que garantem que o chamador mantém seu contrato,
Pós-condições, que garantem que o receptor mantenha seu contrato e
Invariantes, que garantem que a estrutura de dados sempre mantenha alguma propriedade após o retorno da função. Uma invariante é uma condição que é uma pré-condição e uma pós-condição.
Os testes de unidade são úteis para informar sobre o comportamento externo do módulo . Você Stack
pode ter um estado consistente após a push()
chamada do método, mas se o tamanho da pilha não aumentar em três após ser chamado três vezes, isso é um erro. (Por exemplo, o caso trivial em que a push()
implementação incorreta verifica apenas as declarações e saídas.)
A rigor, a principal diferença entre afirmações e testes de unidade é que os testes de unidade possuem dados de teste (valores para executar o programa), enquanto os de afirmações não. Ou seja, você pode executar seus testes de unidade automaticamente, enquanto não pode dizer o mesmo para afirmações. Para o início desta discussão, assumi que você está falando sobre a execução do programa no contexto de testes de funções de ordem superior (que executam todo o programa e não conduzem módulos como testes de unidade). Se você não está falando sobre testes de função automatizados como meio de "ver entradas reais", então claramente o valor está na automação e, portanto, os testes de unidade vencem. Se você está falando sobre isso no contexto de testes de função (automatizados), veja abaixo.
Pode haver alguma sobreposição no que está sendo testado. Por exemplo, a Stack
pós-condição de uma pessoa pode realmente afirmar que o tamanho da pilha aumenta em um. Mas há limites para o que pode ser executado nessa afirmação: ele também deve verificar se o elemento superior foi o que acabou de ser adicionado?
Para ambos, o objetivo é aumentar a qualidade. Para testes de unidade, o objetivo é encontrar erros. Para afirmações, o objetivo é facilitar a depuração, observando estados inválidos do programa assim que eles ocorrem.
Observe que nenhuma técnica verifica a correção. De fato, se você realizar testes de unidade com o objetivo de verificar se o programa está correto, provavelmente encontrará um teste desinteressante que sabe que funcionará. É um efeito psicológico: você fará o que for para atingir seu objetivo. Se seu objetivo é encontrar erros, suas atividades refletirão isso.
Ambos são importantes e têm seus próprios propósitos.
[Como nota final sobre as afirmações: para obter o máximo de valor, você precisa usá-las em todos os pontos críticos do seu programa, e não em algumas funções-chave. Caso contrário, a fonte original do problema pode ter sido mascarada e difícil de detectar sem horas de depuração.]
:-)