Uma das poucas coisas que a maioria dos desenvolvedores de software concorda é que você não deve confiar no código para funcionar corretamente, a menos que você o teste. Se você não testá-lo, pode haver erros ocultos que só irão causar mais trabalho no caminho.
Entendo como testar meu código normal, mas como devo testá-lo para garantir que ele encontre e relate erros de maneira eficaz quando presentes? Pessoalmente, fui estúpido o suficiente para escrever casos de teste errados que passariam quando não deveriam, derrotando, assim, o propósito dos meus testes de escrita. Felizmente, encontrei e corrigi os erros com o tempo, mas, de acordo com o mantra de teste, parece que nenhum conjunto de testes estaria completo sem ter seu próprio conjunto de testes para garantir que funcionasse.
Parece-me que a melhor maneira de fazer isso seria garantir que o teste falhe para o código de buggy. * Se eu passar 2 minutos alternadamente adicionando bugs ao código e me certificando de que ele falhar, eu deveria ter um grau aceitável de confiança de que os testes 'funcionam'. Isso me leva à minha segunda pergunta: Quais são as boas maneiras de introduzir bugs para garantir que eles sejam capturados pelos casos de teste? Devo apenas comentar aleatoriamente declarações, certifique-se o ramo errado de um if-else
é executado negando sua condição e alterar a ordem de execução de código com efeitos colaterais, etc., até que eu estou satisfeito meus testes vai pegar maiserros comuns? Como os desenvolvedores profissionais validam que seus testes realmente fazem o que deveriam fazer? Eles apenas assumem que os testes funcionam, ou eles tomam tempo para testá-los também? Se sim, como eles testam os testes?
Não estou sugerindo que as pessoas devam gastar tanto tempo testando seus testes e testando-os para que nunca escrevam o código real, mas fiz coisas estúpidas o suficiente para me beneficiar um pouco. de 'meta-teste' e estava curioso sobre a melhor maneira de fazer isso. : D
* Eu poderia verificar se o teste é aprovado ao testar o código 'sem erros', mas usar o código como uma especificação para o teste parece um tanto atrasado ...
fonte
Respostas:
O fluxo padrão para TDD é:
O teste para seus testes neste caso é a etapa 1 - verifique se o teste falha antes de fazer alterações no código.
Outro teste de que gosto é se você pode excluir algum código e reimplementá-lo de uma maneira diferente, e seus testes falham após a exclusão, mas funcionam com um algoritmo diferente.
Como em todas as coisas, não há bala mágica. Esquecer-se de escrever um teste obrigatório é tão fácil para um desenvolvedor quanto esquecer de escrever o código. Pelo menos se você estiver fazendo as duas coisas, terá duas vezes mais oportunidades para descobrir sua omissão.
fonte
null
ou não na etapa 1. Você faz a menor alteração de código que o faz passar retornando uma lista vazia. O teste agora é "verde" porque você tem dois erros.null
e não por esvaziar.)Uma abordagem é o Teste de mutação , usando uma ferramenta como o Jester :
fonte
Testes para testes? Não siga por esse caminho. Então você provavelmente precisará de testes para testes para testes e, em seguida, testes para testes para testes para testes ... onde você para?
O fluxo de teste usual é assim e, como desenvolvedor, você passará a maior parte do tempo nos pontos 1 a 3:
Seu código acabará "aumentando" seus próprios bugs, não perca tempo introduzindo-os manualmente. Sem mencionar, uma coisa que você sabia sobre o início é realmente um bug? Erros virão, eu não me preocuparia com isso.
Essa é realmente uma abordagem viável para verificar se você realmente testa o que pensa fazer. Eu não acho que é sempre tão bom , pois sofre do mesmo problema que a coisa "teste para teste para teste ...": quando você para de alterar o código sabendo que está testando 100% funciona?
Também é bom lembrar sobre todos os conselhos pragmáticos clássicos de todos os tempos - você não precisará disso . Seja ágil, escreva testes e codifique erros reais, em vez daqueles hipotéticos que podem ou não aparecer.
fonte
Por construção, o código funcional e o código de teste são testados um contra o outro. Um problema permanece: o caso de erros no modo comum, quando um erro no código funcional é oculto por um erro no código de teste. TDD não é imune a esse efeito. É por isso que o teste geralmente é realizado em vários níveis por pessoas diferentes, a fim de diminuir essa probabilidade.
fonte
Você testa seu teste de unidade uma vez ao escrevê-lo, no depurador. Então você deixa em paz e esquece. Não há problema aqui.
Considere isto. Qual é o objetivo de um teste de unidade? Ele o notifica quando qualquer uma das inúmeras alterações que você fizer no seu programa principal acidentalmente altera a lógica desse programa. Você quer ter isso porque sabe que qualquer alteração potencialmente quebra alguma coisa. É exatamente por isso que não há problema se você não testar seu teste: você não mexe com o teste até alterar propositadamente a lógica do seu programa (o que exigiria que você revisitasse o teste e testasse mais uma vez); Provavelmente, o teste não será interrompido acidentalmente.
fonte
Há um teste de mutação que avalia e mede a adequação e a qualidade do teste.
Podemos usar isso para avaliar "o teste" em si.
Em resumo, podemos avaliar nosso teste (por exemplo, TestA) testando TestA pode encontrar a diferença entre o código e seus códigos de mutação (código muito semelhante, mas um pouco diferente do código original).
Se o TestA não conseguir encontrar a diferença entre o código e seus códigos de mutação, significa que o TestA possui regulamentos muito rígidos para testar o código original.
fonte