Testamos nosso código para torná-lo mais correto (na verdade, é menos provável que esteja incorreto ). No entanto, os testes também são de código - eles também podem conter erros. E se seus testes são com erros, eles dificilmente melhoram seu código.
Posso pensar em três tipos possíveis de erros nos testes:
Erros lógicos, quando o programador não entendeu a tarefa em questão, e os testes fazem o que ele pensou que deveriam fazer, o que está errado;
Erros na estrutura de teste subjacente (por exemplo, uma abstração de simulação com vazamento);
Erros nos testes: o teste está fazendo um pouco diferente do que o programador pensa que é.
Os erros do tipo (1) parecem impossíveis de evitar (a menos que o programador apenas ... fique mais esperto). No entanto, (2) e (3) podem ser tratáveis. Como você lida com esses tipos de erros? Você tem estratégias especiais para evitá-las? Por exemplo, você escreve alguns testes "vazios" especiais, que apenas verificam os pressupostos do autor do teste? Além disso, como você aborda a depuração de um caso de teste quebrado?
fonte
Respostas:
Os testes já estão testados. Os testes são protegidos por design dos erros, porque os testes detectam apenas diferenças entre o código e nossas expectativas. Se houver problemas, temos um erro. O erro pode estar no código ou com a mesma probabilidade nos testes.
Existem algumas técnicas que impedem que você adicione o mesmo bug no seu código e nos testes:
Você não precisa testar a plataforma subjacente. Os testes não apenas exercitam o código escrito por você, mas também executam o código a partir da plataforma. Embora você não precise capturar bugs na plataforma de teste, é muito difícil escrever código e testes que sempre ocultam um bug na plataforma, em outras palavras, é muito difícil ter um bug sistemático nos seus testes / código e na plataforma e a probabilidade é reduzida a cada teste que você cria. Mesmo se você tentasse fazer isso, teria uma tarefa muito difícil.
Você pode ter erros nos testes, mas geralmente eles são capturados facilmente porque os testes são testados pelo código desenvolvido. Entre o código e os testes, você tem um feedback de auto-aplicação. Ambos fazem previsões sobre como uma chamada específica de uma interface deve se comportar. Se a resposta for diferente, você não precisa ter um bug no código. Você também pode ter um bug no teste.
fonte
Tente fazer os testes individuais tão pequenos (curtos) quanto possível.
Isso deve reduzir as chances de criar um bug em primeiro lugar. Mesmo se você conseguir criar um, é mais fácil encontrá-lo. Os testes de unidade devem ser pequenos e específicos, com baixa tolerância a falhas e desvios.
No final, provavelmente é apenas uma questão de experiência. Quanto mais testes você escreve, melhor se torna, menos chance tem de fazer testes ruins.
fonte
A
, você espera resultadoB
. Se você não tem estadoA
, um teste deve falhar. Nesse ponto, você pode investigar por que falhou, más condições iniciais ou um teste ruim, mas deve falhar nos dois casos. Mesmo que seja, como você diz, "um pouco fora" (ou seja"A" => "B"
,"a" => "b"
, mas nunca"a" => "B"
ou seu teste é ruim).Uma tática é escrever o teste antes do código testado e garantir que o teste falhe primeiro pelo motivo certo. Se você usa TDD, deve obter pelo menos esse nível de teste de testes.
Uma maneira mais exaustiva de testar a qualidade de um conjunto de testes é usar o teste de mutação .
fonte
Para os nºs 1 e 3: Os testes de unidade não devem conter lógica, se você o fizer, provavelmente está testando mais de uma coisa no seu teste de unidade. Uma prática recomendada para testes de unidade é ter apenas um teste por teste de unidade.
Assista a este vídeo de Roy Osherove para saber mais sobre como escrever bem os testes de unidade.
fonte
Em termos do nº 1 - acho uma boa ideia emparelhar / revisar código para esse lado das coisas. É fácil fazer pressuposições ou simplesmente fazer as coisas erradas, mas se você precisar explicar o que seu teste está fazendo, qual é o objetivo, é mais provável que você atenda se estiver mirando no alvo errado.
fonte
Deve haver um momento em que se deve parar de tentar o teste de unidade. Deve saber quando traçar a linha. Devemos escrever casos de teste para testar casos de teste? E os novos casos de teste gravados para testar casos de teste? Como vamos testá-los?
Editar: atualizado com a explicação sugerida pelo comentário.
fonte
Ei.
Você tem que aplicativos:
Quando você está executando testes no seu produto, na verdade não está interessado no teste em si, mas na interação entre o produto e os testes. Se o teste falhar, não indica que o aplicativo possui um erro. Diz que a interação entre produto e teste não foi bem-sucedida . Agora é seu trabalho determinar o que deu errado. Pode ser:
Para mim, os testes que falham não são um feedback simples, isso e aquilo estão errados . É um indicador de que há inconsistência, e preciso examinar os dois para verificar se o desejo deu errado. No final, sou responsável por verificar se a aplicação está correta; os testes são apenas uma ferramenta para destacar áreas que podem ser verificadas.
Os testes estão verificando apenas algumas partes do aplicativo. Eu testo a aplicação, eu testo os testes.
fonte
Os testes não devem ser "inteligentes" o suficiente para abrigar erros.
O código que você está escrevendo implementa um conjunto de especificações. (Se X, então Y, a menos que Z, nesse caso Q, etc etc). Todo o teste que você está tentando realizar é determinar que X realmente é Y, a menos que Z, nesse caso Q. Isso significa que tudo o que um teste deve fazer é definir X e verificar Y.
Mas isso não cobre todos os casos, você provavelmente está dizendo e estaria certo. Mas se você tornar o teste "inteligente" o suficiente para saber que X deve apenas por Y, se não Z, estará basicamente reimplementando a lógica de negócios no teste. Isso é problemático por razões que abordaremos um pouco mais abaixo. Você não deve melhorar a cobertura do código tornando seu primeiro teste "mais inteligente"; em vez disso, adicione um segundo teste burro que define X e Z e verifica Q. Dessa forma, você terá dois testes, um que abrange o caso geral ( às vezes também conhecido como caminho feliz) e um que cobre o caso extremo como um teste separado.
Há várias razões para isso. Em primeiro lugar, como você determina se um teste com falha é devido a um erro na lógica de negócios ou a um erro nos testes? Obviamente, a resposta é que, se os testes forem o mais simples possível, é muito improvável que eles estejam abrigando bugs. Se você acha que seus testes precisam ser testados, está testando errado .
Outras razões incluem que você está apenas replicando o esforço (como eu já mencionei, escrever um teste inteligente o suficiente para exercer todas as possibilidades em um único teste é basicamente replicar a lógica de negócios que você está tentando testar em primeiro lugar), se os requisitos mudarem os testes devem ser fáceis de alterar para refletir os novos requisitos, servem como uma espécie de documentação (são uma maneira formal de dizer qual é a especificação da unidade em teste) e assim por diante.
TL: DR: Se seus testes precisam ser testados, você está fazendo errado. Escreva testes idiotas .
fonte
Não é uma resposta (não tenho o privilégio de comentar), mas estava me perguntando se você esqueceu outras razões para desenvolver casos de teste ...
Depois de descobrir todos os erros nos testes, você pode fazer o teste de regressão com facilidade. Os conjuntos de testes automatizados ajudariam a encontrar problemas antes, antes da integração. As alterações nos requisitos são relativamente mais fáceis de serem testadas, pois elas podem se tornar versões mais recentes e alteradas dos casos de teste mais antigos que passam e os casos mais antigos permanecem para detectar falhas.
fonte
Resposta curta: O código de produção testa os testes .
Compare isso com o modelo de crédito / débito usado em economia. A mecânica é muito simples - se o crédito diferir do débito, há algo errado.
o mesmo vale para testes de unidade - Se um teste falhar, isso indica que algo está errado. Pode ser o código de produção, mas também pode ser o código de teste! Esta última parte, se importante.
Observe que seus erros do tipo (1) não podem ser encontrados por testes de unidade. Para evitar esse tipo de erro, você precisa de outras ferramentas.
fonte