Eu tenho um pedaço de código que se parece com isso:
function bool PassesBusinessRules()
{
bool meetsBusinessRules = false;
if (PassesBusinessRule1
&& PassesBusinessRule2
&& PassesBusinessRule3)
{
meetsBusinessRules= true;
}
return meetsBusinessRules;
}
Acredito que deve haver quatro testes de unidade para essa função específica. Três para testar cada uma das condições na instrução if e garantir que ela retorne false. E outro teste que garante que a função retorne verdadeira.
Pergunta: Na verdade, deveria haver dez testes de unidade? Nove que verifica cada um dos possíveis caminhos de falha. IE:
- Falso Falso Falso
- Falso Falso Verdadeiro
- Falso Verdadeiro Falso
E assim por diante para cada combinação possível.
Eu acho que é um exagero, mas alguns dos outros membros da minha equipe não. A maneira como vejo é que, se BusinessRule1 falha, sempre deve retornar falso, não importa se foi verificado primeiro ou por último.
unit-testing
bwalk2895
fonte
fonte
Respostas:
Formalmente, esses tipos de cobertura têm nomes.
Primeiro, há uma cobertura de predicado : você deseja ter um caso de teste que torne a declaração if verdadeira e uma que a false. Ter essa cobertura atendida é provavelmente um requisito básico para um bom conjunto de testes.
Depois, há Cobertura de condição : Aqui você deseja testar se cada sub-condição no if tem o valor verdadeiro e falso. Obviamente, isso cria mais testes, mas geralmente detecta mais bugs; portanto, é uma boa ideia incluir no seu conjunto de testes se você tiver tempo.
Os critérios de cobertura mais avançados geralmente são chamados de Cobertura de condição combinatória : aqui o objetivo é ter um caso de teste que passe por todas as combinações possíveis de valores booleanos em seu teste.
Isso é melhor do que simples cobertura de predicado ou condição? Em termos de cobertura, é claro. Mas não é grátis. Ele tem um custo muito alto na manutenção de testes. Por esse motivo, a maioria das pessoas não se preocupa com a cobertura combinatória completa. Normalmente testar todos os ramos (ou todas as condições) será bom o suficiente para detectar bugs. A adição de testes extras para testes combinatórios não costuma detectar mais erros, mas exige muito esforço para criar e manter. O esforço extra geralmente faz com que isso não valha a recompensa muito pequena, então eu não recomendaria isso.
Parte desta decisão deve se basear em quão arriscado você acha que esse código será. Se houver muito espaço para falhar, vale a pena testar. Se for um pouco estável e não mudar muito, considere concentrar seus esforços de teste em outro lugar.
fonte
Por fim, depende de você (equipe), do código e do ambiente específico do projeto. Não há regra universal. Você (equipe r) deve escrever quantos testes precisar para sentir-se confortável de que o código esteja realmente correto . Portanto, se seus colegas de equipe não estiverem convencidos de quatro testes, talvez você precise de mais.
O tempo da OTOH para escrever testes de unidade geralmente é um recurso escasso. Portanto, lute para encontrar a melhor maneira de gastar o tempo limitado que você tem . Por exemplo, se você tiver outro método importante com cobertura de 0%, pode ser melhor escrever alguns testes de unidade para cobrir esse, em vez de adicionar testes extras para esse método. Obviamente, isso também depende de quão frágil é a implementação de cada um. Planejar muitas mudanças nesse método específico em um futuro próximo pode justificar uma cobertura extra de teste de unidade. Portanto, pode estar em um caminho crítico dentro do programa. Esses são todos os fatores que somente você (equipe r) pode avaliar.
Pessoalmente, normalmente ficaria feliz com os 4 testes que você descreve, ou seja:
mais talvez um:
para garantir que a única maneira de obter um valor de retorno
true
seja satisfazer todas as três regras de negócios. Mas, no final, se seus colegas de equipe insistirem em ter caminhos combinatórios cobertos, pode ser mais barato adicionar esses testes extras do que continuar o argumento por muito mais tempo :-)fonte
Se você quiser estar seguro, precisará de oito testes de unidade usando as condições representadas por uma tabela verdade de três variáveis ( http://teach.valdosta.edu/plmoch/MATH4161/Spring%202004/and_or_if_files/image006.gif ).
Você nunca pode ter certeza de que a lógica de negócios sempre estipula que as verificações são executadas nessa ordem e que você deseja que o teste saiba o mínimo possível sobre a implementação real.
fonte
Sim, deve haver a combinação completa em um mundo ideal.
Ao fazer o teste de unidade, você realmente deve tentar ignorar como o método funciona. Simplesmente forneça as 3 entradas e verifique se a saída está correta.
fonte
Estado é mau. A função a seguir não precisa de um teste de unidade porque não tem efeitos colaterais e é bem entendido o que faz e o que não faz. Por que testá-lo? Você não confia em seu próprio cérebro ??? Funções estáticas são ótimas!
fonte
a
,b
ec
. Você pode mover a lógica de negócios da maneira que quiser, e no final ainda precisa testá-la em algum lugar.Eu sei que esta pergunta é bastante antiga. Mas quero dar outra perspectiva para o problema.
Primeiro, seus testes de unidade devem ter dois propósitos:
what's the class' intention
ehow the class is doing its work
Então, recapitulando o problema, queremos testar a
complex if statement
, para o exemplo dado, existem 2 ^ 3 possibilidades, que é uma quantidade importante de testes que podemos escrever.what is doing the code
Por outro lado, se você está na posição de que seus testes são ainda mais complexos que a implementação, é porque a implementação deve ser reprojetada (mais ou menos, dependendo do caso), e não o próprio teste.
Para as complexas declarações if, por exemplo, você pode pensar no padrão de responsabilidade da cadeia , implementando cada manipulador da seguinte maneira:
If some simple business rule apply, derive to the next handler
Quão simples seria testar várias regras simples, em vez de uma regra complexa?
Espero que ajude,
fonte
Este é um daqueles casos em que Algo como verificação rápida ( http://en.wikipedia.org/wiki/QuickCheck ) será seu amigo. Em vez de escrever todos os N casos manualmente, faça com que o computador gere todos (ou pelo menos um grande número) de possíveis casos de teste e valide se todos retornam um resultado sensato.
Nós programamos computadores para viver aqui, por que não programar o computador para gerar seus casos de teste para você?
fonte
Você pode refatorar as condições em condições de guarda:
Não acho que isso reduz o número de casos, mas minha experiência é que é mais fácil divulgá-los dessa maneira.
(Observe que sou um grande fã do "único ponto de saída", mas faço uma exceção para condições de guarda. Mas existem outras maneiras de estruturar o código para que você não tenha retornos separados.)
fonte