Os testes aprovados desde o início geralmente ocorrem quando alguém implementa algo de uma maneira mais geral do que o necessário para os testes em questão. Isso é bastante normal : os testes de unidade podem fornecer apenas um número pequeno e finito de valores de entrada para uma determinada função, mas a maioria das funções é escrita para uma enorme variedade de possíveis valores de entrada. Geralmente, uma implementação projetada especificamente para os casos de teste atuais seria mais complicada do que uma solução mais geral. Se for esse o caso, seria complicado e propenso a erros projetar artificialmente o código de forma a funcionar apenas nos casos de teste e falhar em todo o resto.
Por exemplo, digamos que você precise de uma função para retornar o mínimo de alguns valores de uma determinada matriz. Você fez uma implementação, conduzida por um teste com uma matriz contendo apenas um ou dois valores. Mas, em vez de implementá-lo de maneira complicada, fazendo comparações em diferentes elementos (talvez apenas os dois primeiros), você chama uma função de mínimo de array da biblioteca padrão do seu ecossistema de idiomas e torna a implementação uma linha única . Quando você agora decide adicionar um teste com uma matriz de cinco elementos, o teste provavelmente será aprovado desde o início.
Mas como você sabe que o teste não é "verde" por causa de um bug no próprio teste? Uma maneira simples e direta de abordar isso é fazer uma modificação temporária no sujeito em teste para que o teste falhe. Por exemplo, você pode adicionar intencionalmente uma linha if (array.size()==5) return 123
à sua função. Agora seu teste de cinco elementos falhará, então você sabe
- o teste é executado
- a chamada Assert no teste é executada
- a chamada Afirmar no teste valida a coisa certa
o que deve lhe dar alguma confiança no teste. Depois de ver o teste falhar, desfaça a modificação e o teste deverá passar novamente.
Como alternativa, você pode modificar o resultado esperado de um teste: digamos que seu teste aprovado contenha uma asserção como
int result = Subject.UnderTest(...);
Assert.AreEqual(1,result);
então você pode editar o teste e substituir o "1" por "2". Quando o teste falha (conforme o esperado), você sabe que funciona como deveria e pode desfazer a substituição e ver se o teste agora fica verde. O risco de introduzir um bug no teste por esse tipo de substituição é muito pequeno; portanto, isso provavelmente é aceitável para a maioria dos casos do mundo real.
Uma maneira diferente, talvez discutível, é definir um ponto de interrupção no teste e usar um depurador para percorrê-lo. Isso também deve dar a você certa confiança de que o código do teste é realmente executado e oferece a possibilidade de validar o caminho através do teste por inspeção passo a passo. No entanto, é preciso ter muito cuidado para não ignorar erros em um caminho de código especificamente para um teste com falha. Para testes complexos, considere fazer as duas coisas - fazendo com que falhe artificialmente e use um depurador para inspecioná-lo.