Embora existam maneiras de impedir que os testes de unidade sejam executados, qual é o valor de verificar os testes de unidade com falha?
Vou usar um exemplo simples: Case Sensitivity. O código atual faz distinção entre maiúsculas e minúsculas. Uma entrada válida para o método é "Cat" e retornaria uma enumeração de Animal.Cat. No entanto, a funcionalidade desejada do método não deve diferenciar maiúsculas de minúsculas. Portanto, se o método descrito fosse aprovado como "gato", ele poderia retornar algo como Animal.Null em vez de Animal.Cat e o teste de unidade falharia. Embora uma simples alteração de código faça com que isso funcione, um problema mais complexo pode levar semanas para ser corrigido, mas identificar o bug com um teste de unidade pode ser uma tarefa menos complexa.
O aplicativo atualmente em análise possui 4 anos de código que "funciona". No entanto, discussões recentes sobre testes de unidade encontraram falhas no código. Alguns precisam apenas de documentação de implementação explícita (por exemplo, com distinção entre maiúsculas e minúsculas) ou código que não executa o bug com base em como ele é chamado atualmente. Porém, testes de unidade podem ser criados executando cenários específicos que farão com que o erro seja visto e sejam entradas válidas.
Qual é o valor do check-in em testes de unidade que exercitam o bug até que alguém possa corrigir o código?
Este teste de unidade deve ser marcado com ignorar, prioridade, categoria etc., para determinar se uma compilação foi bem-sucedida com base nos testes executados? Eventualmente, o teste de unidade deve ser criado para executar o código assim que alguém o corrigir.
Por um lado, mostra que os erros identificados não foram corrigidos. Por outro lado, pode ser difícil encontrar centenas de testes de unidade com falha aparecendo nos logs e eliminar aqueles que devem falhar versus falhas devido a um check-in de código.
fonte
Respostas:
Eu não gosto de unittests quebrados registrados porque produzem ruído desnecessário. Após cada unittest eu teria que verificar todos os problemas com falha (vermelho). Está vermelho porque há um novo problema ou porque existe um antigo aberto para fazer / corrigir. Isso não é bom se houver mais de 20 unittests.
Em vez disso eu uso
[Ignore("Reason")]
atributo que torna o resultado amarelo outhrow new NotImplementedException()
que torna o resultado cinzaNota: Estou usando o NUnit para .net. Não tenho certeza se o recurso "cinza" existe em outras estruturas mais unittest.
Então, eu gosto do seguinte significado dos resultados dos testes de unidade.
Tudo, exceto "vermelho", pode ser verificado.
Para responder à pergunta: há mais mal do que valor em fazer check-in "testados com falha vermelha", mas fazer o check-in "testes ignorados em amarelo" ou "testes cinza-NotImplementedYet" pode ser útil como uma lista de tarefas.
fonte
will probably never be fixed
é uma decisão política se você deseja gastar efford em testes automatizados ou não. Com "testes ignorados", você tem a chance de corrigi-los. Jogando "testes ignorados" longe significa "abandonar testes automatizados por e por até que não haja mais"Não vou fingir que isso é padrão da indústria, mas verifico os testes quebrados como uma maneira de lembrar a mim ou aos meus outros membros do projeto que ainda há um problema no código ou no próprio teste de unidade.
Suponho que uma coisa a considerar é se suas políticas de desenvolvimento permitem testes com falha sem penalidade. Eu tenho um amigo que trabalha em uma loja que faz desenvolvimento orientado a testes, então eles sempre começam com falhas nos testes ...
fonte
Os testes de unidade com falha dão à equipe de desenvolvimento visibilidade do que deve ser feito para estar em conformidade com as especificações acordadas.
Em resumo, os testes de unidade com falha fornecem à equipe uma lista "TODO".
Por esse motivo, os testes de unidade com falha são muito melhores do que nenhum teste de unidade. *
A ausência de testes de unidade deixa a equipe de desenvolvimento no escuro; as especificações devem ser confirmadas repetidamente manualmente .
[* Desde que os testes de unidade realmente testem algo útil.]
fonte
O objetivo dos testes de unidade é afirmar o comportamento esperado de um sistema, não documentar defeitos. Se usarmos testes de unidade para documentar defeitos, a utilidade deles para afirmar o comportamento esperado será reduzida. A resposta para a pergunta "Por que esse teste falhou?" não é um simples "Oh, algo está quebrado que eu não esperava que estivesse quebrado." Tornou-se desconhecido se a falha no teste é esperada ou inesperada.
Aqui está um parágrafo do começo do capítulo 13 de Trabalhando efetivamente com o código legado :
fonte
Mas os quebrados que identificam erros em um novo projeto, nomeado como tal. Dessa forma, você pode ver que eles DEVEM quebrar ... Como estão sendo corrigidos, eles ficam verdes e são movidos para a suíte de testes normal.
NOTA: Esse projeto teria que ser definido para não ser construído no servidor de compilação, se o servidor de compilação impedir checkins que quebram a compilação (supondo que você defina uma compilação quebrada como aquela na qual todos os testes não serão aprovados)
fonte
Os testes de unidade devem testar casos de erro, além de casos de sucesso de uma função. Uma função deve rejeitar explicitamente entrada incorreta ou deve ter documentação para explicar que entrada é considerada válida.
Se você tem uma função que não está fazendo nenhuma dessas coisas, é um bug e você deve ter uma maneira de registrar que ela existe. Criar um teste de unidade que demonstre esse problema é uma maneira de fazer isso. Arquivar um ticket de bug é outra opção.
O objetivo do teste de unidade não é ter 100% de sucesso, o objetivo é encontrar e corrigir bugs no código. Não fazer testes é uma maneira fácil de obter 100% de sucesso, mas isso não é muito benéfico para o projeto.
fonte
Arquive um bug para cada falha e observe isso no resultado do teste. Então, se você agir e corrigir o erro, seu teste será aprovado e você o excluirá do resultado do teste. Nunca apenas ignore problemas.
fonte
Como eu vejo o TDD feito com a implementação de testes para um código inacabado, escreva primeiro os testes com o atributo [ExpectedException] ou similar. Isso deve passar inicialmente, pois o código incompleto não teria lógica e escrever um novo código Exception (). Embora a exceção seja incorreta, isso faria com que os testes passassem inicialmente e se adequassem ao check-in. Podemos esquecer um teste ignorado, mas definitivamente podemos arrumar ou preencher o código incompleto. Quando o fazemos, automaticamente o teste correspondente que estava esperando uma exceção agora começaria a falhar e o alertaria para corrigi-lo. Isso pode envolver uma ligeira alteração no teste para se livrar do ExpectException e, em vez disso, fazer afirmações reais. CI, Dev, testadores e clientes, todos felizes e com uma situação ganha-ganha?
fonte