Um colega meu teve uma ideia que achei interessante.
Não seria vantajoso escrever testes durante a revisão de código, pela pessoa que faz a revisão assumindo que não fazemos TDD?
Para esta questão, suponha que este seja um projeto puramente acadêmico, para que não haja vida em jogo. Além disso, a equipe é de 4 pessoas. Todo mundo conhece a linguagem e está familiarizado com todas as ferramentas / bibliotecas / estruturas usadas e pode escrever testes. Então, basicamente, pessoas que não são engenheiros ninjas líderes seniores, mas codificadores decentes.
Profissionais que encontrei:
- Incentiva uma compreensão mais profunda do código durante a revisão para escrever testes significativos.
- Em seguida, você pode adicionar uma revisão de código dos testes realizados pelo autor do código que está sendo testado.
Contras que encontrei:
- O ciclo de feedback entre a escrita e o teste do código aumenta.
Edição: Eu sei que não vai funcionar bem em aplicativos da web "normais". O que eu tinha em mente era um caso de esquina em que você implementa algoritmos científicos complexos que exigem cuidados com os detalhes. Vamos supor algo como implementar minha própria biblioteca de gráficos, PNL, etc. Gostaria de saber se o código que estamos escrevendo é isolado dos bancos de dados e é muito difícil de compreender, não seria o nível adicional de controle, a outra pessoa que precisa entender a fonte codifique e faça testes significativos, torne todo o processo menos propenso a esses bugs menos óbvios que não travam o aplicativo, mas acabam fazendo com que seus resultados sejam um lixo.
fonte
Respostas:
Descobri que um bom momento para escrever testes é quando você percebe que precisa de um teste para uma situação.
A troca de tarefas para computadores é cara - ainda mais para os humanos.
Neste momento, você geralmente tem um bom entendimento dos requisitos e dependências para o teste. Portanto, aproveite a imersão da sua equipe no problema. Se precisar refinar seu novo teste no futuro, ótimo, você já possui a estrutura / acessórios de teste e tudo o que você precisa fazer é mudar a parte que precisa ser aprimorada.
Se isso acontecer durante a revisão do código, por que não fazer isso? Eu já fiz isso antes. Descobri que é melhor do que não, especialmente se você pode fazê-lo rapidamente, e ainda melhor se não o fizesse de outra forma.
Mesmo se você pratica TDD, se percebe que precisa de um teste enquanto faz a revisão de código, que você não possui, por que não escrever o teste naquele momento?
Prós
É realmente um engodo que mais testes possam levar a mais código? Se o teste foi necessário, e o código foi necessário para o teste, e agora você o possui, isso é uma coisa boa .
Ressalvas
Talvez parte da equipe precise se concentrar em outras coisas. Se isso causa uma distração das prioridades ou a revisão do código excede o cronograma, é necessário limitar ou cortar a gravação real do teste. No entanto, a revisão de código certamente pode identificar testes que precisam ser gravados, e talvez eles possam pelo menos ser descartados para o escritor concluir posteriormente.
fonte
Esta é uma ideia maravilhosa, com uma ressalva. Não substitua testes escritos pelo desenvolvedor por testes escritos pelo revisor. Peça aos seus revisores que procurem casos de canto e entradas que quebrem o código. Em outras palavras, peça que eles tentem escrever novos testes que o desenvolvedor original não pensou em escrever.
Escrever testes de caracterização é uma maneira absolutamente maravilhosa de entender um pedaço de código que você não escreveu. Fazer com que seus revisores realizem testes adicionais no código, oferece a eles uma compreensão muito melhor de como o código funciona, como pode ser quebrado e como pode ser aprimorado. O tempo todo, aumentando sua cobertura de código.
Todas essas são vitórias no meu livro.
fonte
Eu não acho que a idéia seja totalmente sem mérito - no entanto, o principal benefício do TDD et al é que os problemas são encontrados cedo . O desenvolvedor também está em melhor posição para identificar quais casos de canto podem exigir atenção específica. Se isso for deixado até a revisão do código, há um risco de que esse conhecimento possa ser perdido.
Escrever testes durante a revisão de código sofreria o mesmo problema que os testes manuais tradicionais - o entendimento das regras de negócios pode variar de desenvolvedor para desenvolvedor, assim como a diligência.
Há também a discussão antiga que será executada e executada para determinar se os desenvolvedores testariam seu código tão bem se soubessem que havia uma função de teste mais à montante que deveria detectar os bugs mais sérios.
fonte
Concordo com a resposta de @ RobbieDee, mas tenho um pouco mais a acrescentar.
Se você realmente gosta dessa ideia, por que não as mesmas pessoas escrevem os testes antes do código como critérios de aceitação executável para a história do usuário?
Isso faria a mesma coisa, ainda manteria o feedback curto e levaria todos a ter uma discussão sobre a história, o que acho que seria de maior valor.
As desvantagens são o risco de uma reunião interminável de critérios de aceitação :-( e eu acho que você está tentando convencer as pessoas na revisão de código a dar uma olhada no código de implementação, mas eu sugeriria programação de pares e pares rotativos como uma solução melhor para Esse problema.
O OP adicionou uma edição na qual eles detalham mais detalhes sobre esse recurso difícil ou pesado de algoritmo.
Em resposta a isso, acrescentaria que o seu instinto de obter mais olhos no problema e na solução é bom. Talvez emparelhe com várias pessoas, uma a uma, até que todos tenham visto a parte realmente difícil dos códigos e testes de implementação. Cada um lançando novas idéias e agregando mais valor.
Às vezes, há uma idéia chamada programação mob, como emparelhamento, mas com mais pessoas. Isso é quase do que você está falando, mas eles ajudam no momento da redação e não em uma revisão formal depois. Isso não é para todos, e pode exigir um driver forte (líder) para fazê-lo funcionar, ou uma equipe que se sinta muito confortável entre si e com o processo.
Fazendo o que aconteceu depois da programação da multidão, eu acho que teria muitas das mesmas vantagens de muitos olhos vendo o problema e sugerindo melhorias e se é assim que sua equipe está confortável em operar, isso pode ajudar, mas eu realmente tentaria manter o necessário ocorrências disso ao mínimo, pois acho que isso pode atrasar a equipe.
fonte
Como você diz, se você estiver executando uma equipe de TDD, isso é discutível, já que o código já deve ser testado.
No geral, não acho que essa seja uma ótima idéia, mas depende da sua abordagem atual e do que funciona para você. Basicamente, o problema que vejo é que você perde a vantagem do "curto ciclo de feedback" dos testes. Receber notificação instantânea no momento em que você quebra algo, enquanto escreve um novo código, é onde os testes realmente brilham. Se você adiar o teste até a revisão do código, estará basicamente dizendo "bem, poderíamos corrigir esse problema mais cedo em menos tempo e com menos pessoas envolvidas, mas pelo menos todos aprendemos alguma coisa (talvez)". Eu preferiria apenas garantir que as pessoas enviassem o código testado para revisão e, em seguida, você julgue a correção e a manutenção dos testes. Afinal, a revisão de código é para revisar, não para escrever código.
Por outro lado, eu recomendo que você se delicie com os testes / código durante a revisão. Tente quebrar alguma coisa. Comente uma condição if. substitua um booleano por um literal verdadeiro / falso. Veja se os testes estão falhando.
Mas sim, em suma, recomendo que você escreva seus testes junto com o seu código e depois revise tudo de uma vez.
fonte
Depende do que você está fazendo na revisão de código. Eu acho que há duas razões principais para escrever testes nessa fase:
primeiro, se você também refatorar durante a revisão de código e notar que não há testes de unidade suficientes para cobrir o tipo de refatoração que você deseja aplicar, adicione esses testes
segundo, se o código lhe parecer ter um bug e você quiser provar (ou refutar) isso, escreva um teste para ele
Ambos os casos expressam a necessidade de testes que não existem no momento, mas deveriam existir. Obviamente, pode depender da cultura de sua equipe se esse tipo de teste deve ser escrito pelo revisor ou pelo autor original, mas alguém deve escrever os testes.
Na verdade, não acho que seja "um caso de esquina" apenas adequado para "algoritmos científicos complexos" - pelo contrário, é adequado para qualquer tipo de software do qual você espera um certo grau de qualidade.
fonte
Não faça isso. Você os fará pensar que o TDD é horrível.
Eu acho que o @ k3b está certo nos comentários sobre a questão. O código gravado através de um processo no estilo TDD tende a parecer e interagir muito diferente do código gravado sem testes. A adição de (bons) testes ao código não testado geralmente exige muita refatoração do código para esclarecer suas intenções e partes móveis.
Ao adicionar os testes depois de escrever o código, você perde os aspectos arquitetônicos dos benefícios do TDD (que, a meu ver, são um dos principais benefícios). Além disso, você está pedindo a alguém que não esteja tão familiarizado com o código que aceite adicionar testes que já são difíceis de adicionar.
A pessoa que está adicionando testes precisará refatorar significativamente o código ou precisará trabalhar muito para testar o código não testável. De qualquer forma, eles não vão gostar da experiência. Mesmo que este não seja o TDD clássico, eles não o verão dessa maneira, e você pode colocá-los fora do TDD de uma vez por todas.
(Se você já está seguindo um processo de TDD, escrever testes adicionais durante a revisão de código seria menos prejudicial, embora, na minha experiência, se os testes já estiverem bem escritos, é igualmente fácil explicar o teste extra à pessoa que envia o código para revisão e peça que eles os escrevam.)
fonte
Os testes de unidade durante a revisão de código são um mau substituto para os testes de unidade durante o desenvolvimento.
O que você está sugerindo faz muito sentido, intuitivamente. Qual é a revisão? Para verificar se o código está bom. Para que servem os testes? Para verificar se o código está bom. Então, por que não combinar os dois?
Aqui está o porquê.
Colocar o código em teste é um trabalho árduo. Escrever código que simplesmente funciona com a única coisa que deve fazer é uma coisa; escrever código que possa ser testado de maneira eficaz e eficiente é outro. Apenas o fato de o código agora ser executado em dois cenários - "trabalho real" e "teste" - exige muito mais flexibilidade, exige que esse código seja capaz de se sustentar por si próprio de maneira significativa.
Escrever seu código para que seja testável é um trabalho e habilidade extra. Refatorar o código de outra pessoa para testabilidade, quando não foi escrito com a testabilidade em mente, pode ser uma tarefa importante.
Você está duplicando o esforço entre o desenvolvedor e o revisor. Presumivelmente, seu desenvolvedor não está entregando seu código para revisão sem pelo menos algum nível de confiança de que está funcionando. Ele já precisa testar o código. Agora, existem diferentes níveis e escopos de teste. O controle de qualidade testa o código após o desenvolvedor e o revisor. Mas qualquer que seja o escopo que você considere apropriado para o desenvolvedor e o revisor, não faz sentido para o desenvolvedor descobrir como testar o código nesse nível uma vez , mas torne seus testes descartáveis e difíceis de reproduzir e, em seguida, leve o revisor para desenvolver teste novamente, desta vez automatizados e reproduzíveis. Você está apenas fazendo com que ambos invistam tempo escrevendo os mesmos testes - uma vez mal, outra bem.
Você está transformando a revisão em uma etapa muito mais longa e trabalhosa. Se o teste é uma parte importante do processo de revisão, o que acontece quando alguns testes falham ? O revisor é responsável por executar todos os testes e, portanto, também precisa depurar o código? Ou será um pingue-pongue de um lado para o outro, um escrevendo testes, o outro fazendo com que eles passem?
Às vezes, você pode escrever vários testes ortogonais entre si, para não precisar de ping-pong. O revisor escreve uma dúzia de testes, metade deles falha, o desenvolvedor corrige os bugs e todos os testes permanecem válidos e passam agora. Mas ... na maioria das vezes, você tem bugs de bloqueadores, ou que exigem alterações de redesenho e API, ou outros enfeites. Se você está assumindo a responsabilidade de passar nos testes entre o revisor e o desenvolvedor, não está realmente na fase de revisão. Você ainda está desenvolvendo.
A necessidade de escrever testes não incentiva uma revisão mais completa. Basicamente, significa que, quanto mais fundo você vai, mais testes você precisa escrever e provavelmente serão testes difíceis que precisam se aprofundar no sistema.
Compare com o desenvolvedor que está escrevendo os testes, onde está seu incentivo: se eu não escrever testes importantes, o revisor indicará isso na revisão.
Mesmo o revisor terá uma compreensão muito melhor do sistema se precisar passar por testes completos do código , se precisar decidir por si próprio quando pode parar de escrever o teste de escavação profunda e apenas fazer a revisão do código.
Se o desenvolvedor não estiver escrevendo testes de unidade, o revisor também não. Existem muitos obstáculos para a adoção de testes como uma prática comum. Talvez você esteja sob muita pressão e seja difícil colocar sua base de código em teste. Talvez você não seja tão experiente em testes e sinta que não pode pagar a curva de aprendizado. Talvez você tenha um assassino em machado enviando notas ameaçadoras para as pessoas que fazem testes. Eu não sei!
Seja qual for a causa, é seguro apostar que se aplica igualmente ao revisor e ao desenvolvedor. Se a equipe está estressada, o revisor não tem mais tempo do que o desenvolvedor (se tiver, redistribua o trabalho para que as pessoas não fiquem tão estressadas ). Se ninguém souber escrever bem os testes de unidade, o revisor provavelmente também não (se souber, deve sentar-se e ensinar aos colegas de equipe ).
Essa sugestão parece tentar passar a bola de um colega para outro. E eu simplesmente não vejo nenhuma maneira de isso dar certo, em primeiro lugar, porque é realmente difícil (e doentio) criar uma situação em que uma pessoa é a única que pode fazer testes e outra não pode fazer qualquer teste.
O que funciona é ter a revisão para cobrir os testes também. Se o desenvolvedor já escreveu dez testes, é muito mais provável que o revisor possa ajudar a sugerir outros dez, do que se o desenvolvedor não tivesse escrito nenhum.
E, se testar casos de esquina é uma tarefa importante, pode fazer sentido distribuí-lo mais amplamente por toda a equipe. ** Uma vez que o código é testável, escrever mais testes se torna muito mais fácil. **
A revisão é um ótimo momento para identificar casos de canto. E, se o revisor puder entrar e escrever um teste para os casos de canto que encontrar, então ei - melhor ainda! Mas de um modo geral, supondo que o revisor possa escrever testes nos quais o desenvolvedor não parece uma péssima idéia.
fonte