Devemos sempre testar os erros de unidade ao corrigi-los?


29

Ao corrigir bugs, é recomendável que eu trabalhe primeiro para escrever um teste que falhe com o bug especificado e, em seguida, para corrigir o código até que o teste passe. Isso segue as práticas de TDD e deve ser uma boa prática, mas notei que tende a produzir testes enigmáticos que se aproximam muito da implementação.

Por exemplo, tivemos um problema quando um trabalho foi enviado, atingiu um determinado estado, foi abortado e repetido. Para reproduzir esse bug, um teste maciço foi escrito com sincronização de threads, muitas zombarias e outras coisas ... Ele fez o trabalho, mas agora que refatoro o código, acho muito tentador remover esse mamute, já que realmente exigiria muito trabalho (novamente) para se ajustar ao novo design. E está apenas testando um pequeno recurso em um único caso específico.

Daí a minha pergunta: como você testa bugs difíceis de reproduzir? Como você evita criar coisas que testam a implementação e prejudicam a refatoração e a legibilidade?


Esse caso de erro é relevante para o novo design? Para mim, parte de um novo design seria aumentar a confiabilidade do design; portanto, você poderá usá-lo para justificar a remoção deste caso de teste, se esse tipo de bug tiver algo a ver com um erro no design original.
Timina

o refator é sobre outra coisa, e ainda é possível, no novo design, modificar levemente o código e reintroduzir o bug, que é o que o teste está assistindo. Eu acho que uma alternativa para o teste seria um comentário no código dizendo "não brinque com isso", mas parece que a coisa errada a fazer: p
Zonko

1
se é demasiado complexo para um unittest torná-lo parte do teste de integração
aberração catraca

Parece que isso precisa de um teste de integração e não de um teste de unidade. Baseado no fato de que você está zombando muito. Uma regra geral que eu vi é que você não testa código que fala com componentes fora da sua base de código (conversando com um banco de dados, lendo a partir do sistema de arquivos, etc.), que soa como o que está fazendo também.
Lucas

Respostas:


27

Sim, em geral você deveria . Como em todas as diretrizes, você precisará usar seu bom senso quando elas forem contra outras diretrizes. Nesse cenário, a gravidade do bug precisa ser ponderada em relação ao trabalho necessário para implementar o teste e a qualidade desse teste, sendo direcionada ao problema de negócios e capturando a regressão do estado do bug.

Eu tenderia a preferir escrever testes do que não, já que as interrupções na execução de erros tendem a ter mais sobrecarga do que simplesmente desenvolver e manter um teste de unidade.


Eu acrescentaria mais ênfase a isso e declararia que, em um mundo ideal, só seria considerado um bug se existir um teste de unidade com falha, mas +1 para o itálico e observando que as necessidades de negócios devem prevalecer.
Joshua Drake

2
bem, na verdade, no final, trata-se de um equilíbrio entre o tempo necessário para manter o teste e o tempo que levaria para um noob detectar e corrigir o erro se isso acontecesse novamente.
Zonko

Também gostaria de favorecer a generalização do teste para que ele não está apenas testando abortar e tentar novamente o trabalho quando ele atinge um estado específico, mas sim testes de abortar e tentar novamente a cada estado um emprego poderia estar.
Old Pro

+1 em "uma vez que as interrupções para corrigir erros tendem a ter mais sobrecarga do que simplesmente desenvolver e manter um teste de unidade".
Peter K.

16

Acho que a melhor prática - que tenho vergonha de admitir que não sigo com frequência - é criar um sistema ou teste de integração que demonstre o problema observado na produção e pesquisar para encontrar a (s) unidade (s) responsável (s) pelo problema, e, em seguida, escreva testes de unidade para as unidades que demonstram o problema no nível da unidade . Depois de fazer os testes de unidade, conserte as unidades e execute todos os testes. Nesse ponto, pode ser prudente descartar o teste original - porque pode ser frágil e / ou lento -, mas mantenha os testes de unidade em seu pacote automatizado para fins de regressão e cobertura.


7

A prática de escrever um teste para identificar o defeito é uma boa ideia, pois permite identificar exatamente quais etapas são necessárias para reproduzir o defeito e verificar se ele foi corrigido. Além disso, esses testes podem ser executados como parte dos testes de fumaça ou de regressão para garantir que alterações posteriores não reintroduzam um defeito antigo no sistema.

A primeira coisa a considerar é o nível do teste necessário. Talvez o teste para verificar a correção seja mais apropriado no nível do sistema ou até mesmo um teste de aceitação feito manualmente. Eu acho que é mais importante ter um teste documentado e gerenciado, independentemente de como ele é implementado especificamente.

Na medida em que a refatoração afeta os testes, isso depende das características específicas. Em alguns casos, a refatoração (ou qualquer tipo de trabalho, como novos recursos) pode tornar os testes desnecessários. O problema, como ocorreu originalmente, pode não ser mais possível. Nesse caso, pode ser aconselhável remover o teste dos possíveis testes para tornar seu processo de teste (automatizado ou manual) mais enxuto. Em outros casos, existem vários métodos para executar o teste e verificar o recurso em um nível diferente, podendo ser mais apropriado. Se o recurso for menor, talvez o teste não seja mais necessário.

Você também pode considerar não apenas confiar nos testes, mas também fazer o log. Por exemplo, capturando informações em tempo de execução (com níveis variados de detalhamento dependendo do ambiente - mais detalhado durante o teste, menos detalhado durante a implantação), criando um perfil do aplicativo, capturando despejos do estado atual do sistema. Se você puder encontrar gatilhos comuns para o problema, poderá usá-lo para orientar os testes em todos os níveis.


5

Sim você deveria.

Escreva testes de unidade para a base de código existente. Ao corrigir um bug, você precisa garantir que seu teste de unidade falhe - isso lhe dará confiança de que você está realmente trabalhando em um bug. Você precisa refatorar e fazer o teste passar corrigindo o erro.

Esta não é uma prática TDD. Nos testes TDD, conduza seu design, mas no seu caso, o design já foi decidido.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.