Suponha que um deles tenha um programa relativamente grande (digamos, 900k SLOC em C #), todos comentados / documentados minuciosamente, bem organizados e funcionando bem. Toda a base de código foi escrita por um único desenvolvedor sênior que não está mais na empresa. Todo o código é testável como está e a IoC é usada o tempo todo - exceto por algum motivo estranho, eles não escreveram nenhum teste de unidade. Agora, sua empresa deseja ramificar o código e deseja que testes de unidade sejam adicionados para detectar quando as alterações quebram a funcionalidade principal.
- A adição de testes é uma boa ideia?
- Se sim, como alguém começaria algo assim?
EDITAR
OK, então eu não esperava respostas apresentando bons argumentos para conclusões opostas. O problema pode estar fora do meu controle. Também li as "perguntas duplicadas" e o consenso geral é que "escrever testes é bom" ... sim, mas não é muito útil nesse caso em particular.
Acho que não estou sozinho aqui pensando em escrever testes para um sistema legado. Vou manter métricas sobre quanto tempo é gasto e quantas vezes os novos testes detectam problemas (e quantas vezes não). Voltarei e atualizarei isso daqui a um ano ou mais com meus resultados.
CONCLUSÃO
Portanto, é basicamente impossível simplesmente adicionar teste de unidade ao código existente com qualquer aparência de ortodoxia. Uma vez que o código está funcionando, você obviamente não pode colocar luz vermelha / luz verde em seus testes, geralmente não está claro quais comportamentos são importantes para testar, não está claro por onde começar e, certamente, não está claro quando você termina. Realmente, mesmo fazer essa pergunta perde o ponto principal de escrever testes em primeiro lugar. Na maioria dos casos, achei mais fácil reescrever o código usando TDD do que decifrar as funções pretendidas e adicionar retroativamente os testes de unidade. Ao corrigir um problema ou adicionar um novo recurso, é uma história diferente, e acredito que este é o momento de adicionar testes de unidade (como alguns apontaram abaixo). Eventualmente, a maioria dos códigos é reescrita, geralmente mais cedo do que você esperaria.
fonte
Respostas:
Embora os testes sejam uma boa idéia, a intenção era que o codificador original os construísse enquanto criava o aplicativo para capturar seu conhecimento de como o código deveria funcionar e o que pode quebrar, o que seria transferido para você.
Ao adotar essa abordagem, há uma alta probabilidade de você escrever os testes com menor probabilidade de quebrar e perder a maioria dos casos extremos que teriam sido descobertos ao criar o aplicativo.
O problema é que a maior parte do valor virá dessas 'pegadinhas' e situações menos óbvias. Sem esses testes, o conjunto de testes perde praticamente toda a sua eficácia. Além disso, a empresa terá uma falsa sensação de segurança em torno de seu aplicativo, pois não será significativamente mais à prova de regressão.
Normalmente, a maneira de lidar com esse tipo de base de código é escrever testes para o novo código e para a refatoração do código antigo até que a base de código herdada seja totalmente refatorada.
Veja também .
fonte
Sim, adicionar testes é definitivamente uma boa ideia.
Você diz que está bem documentado, e isso o coloca em uma boa posição. Tente criar testes usando essa documentação como guia, concentrando-se em partes do sistema que são críticas ou estão sujeitas a alterações frequentes.
Inicialmente, o tamanho da base de código provavelmente parecerá impressionante em comparação com a pequena quantidade de testes, mas não existe uma abordagem do big bang, e começar em algum lugar é mais importante do que agonizar sobre qual será a melhor abordagem.
Eu recomendaria o livro de Michael Feathers, Working Effective with Legacy Code , por alguns bons conselhos detalhados.
fonte
Nem todos os testes de unidade têm benefícios iguais. O benefício de um teste de unidade ocorre quando falha. Quanto menor a probabilidade de falhar, menos benéfico é. O código novo ou alterado recentemente tem mais probabilidade de conter erros do que o código raramente alterado que é bem testado na produção. Portanto, é mais provável que testes de unidade em código novo ou alterado recentemente sejam mais benéficos.
Nem todos os testes de unidade têm custo igual. É muito mais fácil testar o código trivial que você projetou hoje do que o código complexo que outra pessoa projetou há muito tempo. Além disso, o teste durante o desenvolvimento geralmente economiza tempo de desenvolvimento. No código legado, a economia de custos não está mais disponível.
Em um mundo ideal, você teria todo o tempo necessário para testar o código legado de unidade, mas no mundo real, em algum momento, é lógico que os custos de adicionar testes de unidade ao código legado superem os benefícios. O truque é identificar esse ponto. Seu controle de versão pode ajudar, mostrando o código alterado mais recentemente e alterado com mais freqüência, e você pode começar colocando-os em teste de unidade. Além disso, quando você fizer alterações no futuro, coloque essas alterações e o código intimamente relacionado em teste de unidade.
Seguindo esse método, eventualmente você terá uma cobertura muito boa nas áreas mais benéficas. Se você passar meses instalando testes de unidade antes de retomar as atividades geradoras de receita, pode ser uma decisão desejável de manutenção de software, mas é uma péssima decisão comercial.
fonte
Absolutamente, embora eu ache um pouco difícil acreditar que o código esteja limpo e funcionando bem e usando técnicas modernas e simplesmente não tenha testes de unidade. Tem certeza de que eles não estão em uma solução separada?
De qualquer forma, se você deseja estender / manter o código, os verdadeiros testes de unidade são inestimáveis para esse processo.
Um passo de cada vez. Se você não estiver familiarizado com o teste de unidade, aprenda um pouco. Assim que se familiarizar com os conceitos, escolha uma pequena seção do código e escreva testes para ele. Depois o próximo e o próximo. A cobertura do código pode ajudá-lo a encontrar pontos que você perdeu.
Provavelmente é melhor escolher coisas perigosas / arriscadas / vitais para testar primeiro, mas você pode ser mais eficaz testando algo direto para entrar primeiro em um ritmo - especialmente se você / a equipe não estiver acostumada à base de código e / ou unidade Testando.
fonte
Sim, fazer testes é uma boa ideia. Eles ajudarão a documentar que a base de código existente funciona como pretendido e capturar qualquer comportamento inesperado. Mesmo se os testes falharem inicialmente, deixe-os e refatore o código mais tarde para que eles passem e se comportem como pretendido.
Comece a escrever testes para classes menores (aquelas que não têm dependências e são relativamente simples) e passe para classes maiores (aquelas que têm dependências e são mais complexas). Vai levar muito tempo, mas seja paciente e persistente para que você possa cobrir a base de código o máximo possível.
fonte
OK, eu vou dar a opinião contrária ....
A adição de testes a um sistema em funcionamento existente alterará esse sistema, a menos que seja, o sistema será todo escrito com zombaria desde o início. Duvido, embora seja bem possível que tenha uma boa separação de todos os componentes com limites facilmente definíveis nos quais você pode inserir suas interfaces simuladas. Mas se não for, você terá que fazer mudanças bastante significativas (relativamente falando) que podem muito bem quebrar as coisas. Na melhor das hipóteses, você gastará muito tempo escrevendo esses testes, tempo que poderia ser melhor gasto escrevendo vários documentos detalhados de design, documentos de análise de impacto ou documentos de configuração da solução. Afinal, esse é o trabalho que seu chefe deseja mais do que testes de unidade. Não é?
Enfim, eu não adicionaria nenhum teste de unidade.
Eu me concentrava em ferramentas de teste automatizadas externas, que oferecem uma cobertura razoável sem alterar nada. Então, quando você vier fazer modificações ... é aí que você poderá começar a adicionar testes de unidade dentro da base de código.
fonte
Frequentemente, já deparei com essa situação, herdo uma grande base de códigos sem cobertura adequada ou sem cobertura de teste e agora sou responsável por adicionar funcionalidade, corrigir bugs etc.
Meu conselho é garantir e testar o que você adiciona e, se você corrigir bugs ou alterar casos de uso no código atual, o autor testa. Se você precisar tocar em algo, escreva testes nesse ponto.
Quando isso ocorre, quando o código existente não está bem estruturado para testes de unidade, você gasta muito tempo refatorando para poder adicionar testes para pequenas alterações.
fonte