Eu introduzi testes de unidade em bases de código que não possuíam anteriormente. O último grande projeto em que estive envolvido, onde o produto já estava em produção, com zero teste de unidade quando cheguei à equipe. Quando saí - dois anos depois -, tínhamos mais de 4500 testes produzindo cerca de 33% de cobertura de código em uma base de código com 230.000 + de produção LOC (aplicativo Win-Forms financeiro em tempo real). Isso pode parecer baixo, mas o resultado foi uma melhoria significativa na qualidade do código e na taxa de defeitos - além de melhorar o moral e a lucratividade.
Isso pode ser feito quando você tem um entendimento e um compromisso precisos das partes envolvidas.
Primeiro de tudo, é importante entender que o teste de unidade é uma habilidade em si. Você pode ser um programador muito produtivo de acordo com os padrões "convencionais" e ainda se esforçar para escrever testes de unidade de uma maneira que seja escalável em um projeto maior.
Além disso, e especificamente para sua situação, adicionar testes de unidade a uma base de código existente que não possui testes também é uma habilidade especializada. A menos que você ou alguém da sua equipe tenha uma experiência bem-sucedida com a introdução de testes de unidade em uma base de código existente, eu diria que a leitura do livro de Feather é um requisito (não é opcional ou é altamente recomendável).
Fazer a transição para o teste de unidade de seu código é um investimento em pessoas e habilidades, tanto quanto na qualidade da base de código. Compreender isso é muito importante em termos de mentalidade e gerenciamento de expectativas.
Agora, para seus comentários e perguntas:
No entanto, estou preocupado que acabe perdendo o quadro geral e acabe perdendo os testes fundamentais que teriam sido incluídos se eu tivesse usado o TDD desde o início.
Resposta curta: Sim, você perderá os testes e sim, eles podem não parecer inicialmente com o que teriam em uma situação de campo verde.
A resposta em nível mais profundo é esta: não importa. Você começa sem testes. Comece a adicionar testes e refatorar à medida que avança. À medida que os níveis de habilidade melhorarem, comece a elevar os padrões para todo o código recém-escrito adicionado ao seu projeto. Continue melhorando etc ...
Agora, lendo as entrelinhas aqui, tenho a impressão de que isso vem da mentalidade de "perfeição como desculpa para não agir". Uma mentalidade melhor é se concentrar na autoconfiança. Portanto, como você ainda não sabe como fazê-lo, descobrirá como proceder e preenche os espaços em branco. Portanto, não há razão para se preocupar.
Novamente, é uma habilidade. Você não pode passar de zero testes à perfeição TDD em uma abordagem de "processo" ou "passo a passo" de livros de culinária de maneira linear. Será um processo. Suas expectativas devem ser de progresso e aprimoramento graduais e incrementais. Não há pílula mágica.
A boa notícia é que, com o passar dos meses (e até anos), seu código gradualmente começará a se tornar um código "adequado", bem fatorado e testado.
Como uma nota rodapé. Você descobrirá que o principal obstáculo para a introdução de testes de unidade em uma antiga base de código é a falta de coesão e dependências excessivas. Portanto, você provavelmente descobrirá que a habilidade mais importante será como quebrar as dependências existentes e dissociar o código, em vez de escrever os próprios testes de unidade.
Há algum processo / etapas que devem ser seguidos para garantir que as soluções existentes sejam adequadamente testadas em unidade e não apenas incorporadas?
A menos que você já o tenha, configure um servidor de compilação e configure uma compilação de integração contínua que seja executada em cada check-in, incluindo todos os testes de unidade com cobertura de código.
Treine seu pessoal.
Comece em algum lugar e comece a adicionar testes enquanto progride da perspectiva do cliente (veja abaixo).
Use a cobertura do código como uma referência orientadora de quanto da sua base de código de produção está sendo testada.
O tempo de construção deve ser sempre RÁPIDO. Se o seu tempo de construção for lento, suas habilidades de teste de unidade estão atrasadas. Encontre os testes lentos e aprimore-os (desacople o código de produção e teste isoladamente). Bem escrito, você deve ser capaz de realizar vários milhares de testes de unidade e ainda concluir uma compilação em menos de 10 minutos (~ 1-poucos ms / teste é uma diretriz boa, mas muito grosseira, algumas poucas exceções podem ser aplicadas como código usando reflexão etc.) )
Inspecione e adapte.
Como posso garantir que os testes sejam de boa qualidade e que não sejam apenas um caso de teste, é melhor que nenhum teste.
Seu próprio julgamento deve ser sua principal fonte de realidade. Não há métrica que possa substituir a habilidade.
Se você não tiver essa experiência ou julgamento, considere contratar alguém que o faça.
Dois indicadores secundários aproximados são a cobertura total do código e a velocidade de construção.
Vale a pena o esforço para uma solução existente em produção?
Sim. A grande maioria do dinheiro gasto em um sistema ou solução personalizada é gasta depois que é colocada em produção. E investir em qualidade, pessoas e habilidades nunca deve estar fora de moda.
É melhor ignorar o teste para este projeto e adicioná-lo em uma possível reescrita futura?
Você teria que levar em consideração, não apenas o investimento em pessoas e habilidades, mas o mais importante, o custo total de propriedade e o tempo de vida útil esperado do sistema.
Minha resposta pessoal seria "sim, é claro" na maioria dos casos, porque eu sei que é muito melhor, mas reconheço que pode haver exceções.
O que será mais benéfico; passando algumas semanas adicionando testes ou algumas semanas adicionando funcionalidade?
Nem. Sua abordagem deve ser adicionar testes à sua base de código enquanto você está progredindo em termos de funcionalidade.
Novamente, é um investimento em pessoas, habilidades E na qualidade da base de código e, como tal, exigirá tempo. Os membros da equipe precisam aprender como quebrar dependências, escrever testes de unidade, aprender novos hábitos, melhorar a disciplina e a conscientização da qualidade, como projetar melhor o software etc. É importante entender que, quando você começa a adicionar testes, é provável que os membros da equipe não o façam ainda têm essas habilidades no nível necessário para que essa abordagem seja bem-sucedida, portanto, interromper o progresso para gastar todo o tempo para adicionar muitos testes simplesmente não funcionará.
Além disso, adicionar testes de unidade a uma base de código existente de qualquer tamanho considerável de projeto é uma grande tarefa que exige comprometimento e persistência. Você não pode mudar algo fundamental, esperar muito aprendizado pelo caminho e pedir ao seu patrocinador que não espere nenhum ROI, interrompendo o fluxo de valor comercial. Isso não vai voar e, francamente, não deveria.
Em terceiro lugar, você deseja incutir valores sólidos de foco nos negócios em sua equipe. A qualidade nunca chega às custas do cliente e você não pode ir rápido sem qualidade. Além disso, o cliente está vivendo em um mundo em mudança, e seu trabalho é facilitar sua adaptação. O alinhamento do cliente requer qualidade e fluxo de valor comercial.
O que você está fazendo é pagar dívidas técnicas. E você está fazendo isso enquanto ainda atende a seus clientes, sempre mudando as necessidades. Gradualmente, com o pagamento da dívida, a situação melhora e é mais fácil atender melhor ao cliente e agregar mais valor. Etc. Esse momento positivo é o que você deve buscar, porque sublinha os princípios do ritmo sustentável e manterá e melhorará a moral - tanto para sua equipe de desenvolvimento, seu cliente quanto seus stakeholders.
espero que ajude