Qual é a verdadeira sobrecarga do TDD quando toda a equipe está acostumada?

24

Qual porcentagem de tempo é economizada e custada com TDD.

Presumo que essa porcentagem de mudanças de custo e recompensa durante o ciclo de vida de um projeto.

Imagino que a fase inicial tenha muito mais custo, mas poucas recompensas. Mais adiante (durante a re-fatoração ), você obtém o benefício de seus testes.

Ouvi dizer que de 30 a 50% do seu tempo está escrevendo testes de unidade. No entanto, isso não leva em consideração o tempo economizado na gravação desses testes.

Qual é a experiência de todos com isso?

Wes

EDITAR Qual é o tempo economizado e o custo de tempo? Na correção de erros e na refatorabilidade?

Wes
fonte
Escreva testes antes de codificar ou escreva testes depois. Eu sentiria que a sobrecarga é insignificante, da mesma forma que você escreve testes.
Chris
1
@ Chris, quando você escreve os testes primeiro, cria a API com antecedência, em vez disso, como uma reflexão tardia.
3
@ Thorbjørn: Concordo com sua observação, embora seja inteiramente possível projetar uma API sem usar TDD, dificilmente uma reflexão tardia.
Robert Harvey
2
@ Steven: Sim, eu sei o que é TDD. É interessante você dizer que projetar a API antecipadamente. Isso me parece uma abordagem sólida. Nunca fui completamente convencido de que você pode "crescer" uma API escrevendo vários testes.
Robert Harvey

Respostas:

8

Ouvi dizer que de 30 a 50% do seu tempo está escrevendo testes de unidade. No entanto, isso não leva em consideração o tempo economizado

Na minha experiência, são mais de 50%.

Depois de escrever o teste, a solução tenderá a ser muito fácil. Portanto, não acho estranho gastar 70% - 75% do seu tempo escrevendo testes, mas você está gastando muito menos tempo escrevendo o 'código de produção' (código sendo testado) e praticamente não passando tempo no depurador .

Quanto mais cedo você encontrar um bug, mais barato será o reparo e o TDD ajudará tremendamente com isso. Eu trabalhei em projetos nos quais os últimos 2 meses (de um projeto de 8 meses) foram gastos corrigindo bugs, e essa fase seria quase totalmente eliminada com o TDD.

Para mim, porém, o valor real está em manutenção. Herdar uma base de código com testes deixa você com menos medo de alterá-la. Você sente que não quebrou nada quando os testes ainda passam. Como você não tem medo de fazer alterações, está disposto a refatorar se algo não estiver certo. O que significa que o código pode ficar mais limpo, o design pode se ajustar melhor e, em teoria, as alterações podem ser aplicadas. Compare isso com o código vodu que todo mundo tem medo de tocar.

Brad Cupit
fonte
Se os testes são bons testes. No entanto, alguns são melhores que nenhum, e geralmente você pode dizer com muita rapidez olhando se o teste é bom ou não.
Michael K
1
então você acha que há uma economia real e tangível no tempo. (2 meses) de acordo com o seu exemplo, mas quanto tempo seria gasto nos testes? Boa resposta entre.
Wes
@ Wes É muito difícil saber. Escrevo o código em teste mais rápido, mas passo muito tempo nos testes, o que me ajuda a encontrar erros mais cedo, o que economiza tempo, mas não sei quanto tempo ele economizou desde que não encontrei o bug tarde! Pessoalmente, acho que o TDD custa mais a curto prazo, mas economiza mais a longo prazo. Quanto mais longo o projeto, mais ele se beneficia.
Brad Cupit
Movi isso para a minha resposta confirmada agora.
Wes
15

Cada vez que você executa seus testes de unidade, economiza o tempo necessário para testar seu código manualmente.

Os 30% a 50% do tempo que você cita como necessário para escrever seus testes também são compensados ​​pelos benefícios de ter um design de software melhor (testável).


Digamos que leva quatro vezes mais tempo para escrever um teste automatizado do que para executar manualmente o teste. Isso significa que, na quarta vez em que você executa seu teste automatizado, ele se paga. Toda vez que você executa o teste automatizado, é grátis.

Isso vale se o teste é um teste de unidade automatizado ou um teste funcional automatizado. Nem todos os testes funcionais podem ser automatizados, mas muitos podem. Além disso, o teste automatizado é mais confiável que uma pessoa; Ele executará o teste exatamente da mesma maneira , sempre.

A realização de testes de unidade significa que você pode refatorar a implementação subjacente de um método (por desempenho ou outros motivos), e os testes de unidade verificarão se a funcionalidade do método não foi alterada. Isto é especialmente verdade no TDD, onde o teste de unidade especifica a funcionalidade do método.

Robert Harvey
fonte
Não estou convencido de que você se salve de testes manuais. TBH. Para garantir que algo funcione funcionalmente, você ainda deve usar a regressão pelo menos até onde eu sei.
Wes
6
Testes de unidade são testes de regressão. Não tenho certeza do que você está dizendo.
Robert Harvey
2
Testes de unidade e testes funcionais são ambas formas de teste de regressão. Eu acho que Wes está se referindo a este último.
Phil Mander
@ Phil Mander exatamente certo. @ Robert Harvey Eu quis dizer testes funcionais, meu cérebro não encontrou a palavra certa. Embora eu tenha certeza de que meu subconsciente fez como eu usei a palavra funcionalmente lá: S Oh e boa edição btw.
Wes
Eu não acho que executar o teste exatamente da mesma maneira todas as vezes seja realmente positivo, pois é possível sentir muita falta de encontrar problemas como esse de maneira consistente.
precisa
5

O TDD é frequentemente medido em relação à qualidade do código, em vez do tempo e custo gastos. No entanto, com melhor qualidade de código, os desenvolvedores e todas as pessoas que trabalham com eles podem trabalhar melhor (menos tempo gasto, menos custos envolvidos, mais felizes etc.). http://davidlongstreet.wordpress.com/2009/04/29/new-software-metric-wtfs-per-minute/

Escrever testes é ótimo para ajudar a automatizar a verificação de requisitos funcionais e não funcionais. Um vídeo que me convenceu a adotar TDD (na verdade, BDD, TDD de alto nível): http://video.google.com/videoplay?docid=8135690990081075324#

  • Escrever testes funcionais pode ajudar a detectar bugs / problemas mais cedo durante a fase de desenvolvimento . Suponha que você tenha uma grande base de código. Com testes / especificações de unidade , você só precisa ver "Todos os testes aprovados" / "2 testes falharam, consulte a linha xyz". Você só precisa de uma equipe de desenvolvedores para desenvolver e testar. Sem testes / especificações de unidade , você precisa comparar manualmente as instruções impressas com as esperadas e rastrear manualmente quais métodos / classes têm bugs. Você provavelmente precisa de duas equipes separadas (desenvolvedores e testadores) para fazer isso.

  • Testes escritos ajudam os desenvolvedores a explicar o progresso e os problemas enfrentados.

  • O TDD ajuda a cumprir a capacidade de manutenção, adaptabilidade e flexibilidade do código. Ele encoraja os desenvolvedores a escrever pequenos pedaços testáveis ​​e agrupá-los em pedaços maiores testáveis. O contrário (parte da prática de refatoração) também funciona, com a condição de termos escrito testes sólidos. Como resultado, podemos ter um código modular bem escrito.

Com o TDD, temos o prazer de saber quando:

  • um cliente solicita alterações nos requisitos (satisfazendo os requisitos)
  • melhores maneiras de escrever código são descobertas
  • companheiros de equipe têm sugestões para aprimoramento de código
  • nós temos que explicar / passar nosso código para outras pessoas

O TDD pode ser chato porque o processo de desenvolvimento dá pequenos passos e, portanto, se torna tão previsível.

n193853
fonte
4

No nosso caso, eu estimaria que fosse perto de 40%. No entanto, acho que não passamos por uma fase em que foi mais do que isso. Temos um gerador de código que expõe um esqueleto de código que é aprimorado pelos desenvolvedores e um conjunto de testes que também é aprimorado. A maior parte de nosso esforço de teste é direcionada ao rastreamento (ou criação) de dados de teste apropriados para garantir que obtenhamos uma cobertura completa.

TMN
fonte
É um gerador de código desenvolvido em casa ou um gerador de código-fonte aberto que está disponível na natureza?
Robert Harvey
É uma solução manual, baseada nas classes .NET CodeDOM.
TMN
3

as medidas importantes a longo prazo não são apenas a qualidade e a confiança do código, mas também não queimam a equipe fazendo testes irracionais

as medidas de curto prazo seriam o ROI da automação dos testes

por exemplo: na semana passada, fiz mais de 1000 alterações de código devido a uma mudança na arquitetura interna, iniciei o conjunto de testes automatizados e fui dormir.

os testes levaram 28 minutos para serem executados; todos eles passaram. a execução manual dos mesmos 40 ou mais testes de aceitação levaria cerca de 6 horas.

outro exemplo: em uma iteração anterior, eu havia inventado um dos cenários de teste com um bug sutil que o teste manual provavelmente não teria encontrado (os testes automatizados executam verificações de integridade do banco de dados que os testadores manuais quase nunca fazem). Eu tive que executar esse cenário de teste cerca de 50 vezes antes de conseguir descobrir e corrigi-lo. executar manualmente as operações do cenário de teste levaria cerca de 50 minutos. São 41,6 horas de trabalho-homem economizadas em um dia

não há como calcular antecipadamente o ROI dos testes automatizados, porque você não pode saber exatamente quantas vezes precisará executar os testes.

mas para mim, o ROI dos testes automatizados é quase infinito

Steven A. Lowe
fonte
1
Oh, isso é um ponto interessante. Eu pensei que as verificações de integridade do banco de dados deveriam estar fora dos testes de unidade. Que outros testes, além dos testes de unidade, você executa de forma automatizada?
Wes
1
@ Wes: os testes no TDD são chamados de testes "unitários", mas não deixe que esse nome infeliz limite seu escopo. Seu objetivo é testar os recursos . Um recurso pode ser 'a função foo sempre retorna nula' ou pode ser 'a latência geral do sistema sob carga máxima deve ser menor que 12 picossegundos'.
Steven A. Lowe
0

Isso pode ajudar bastante a restringir testes de unidade a algoritmos complexos, casos em que eles podem ser gerados automaticamente e regressões.

O teste de componente geralmente faz um ótimo trabalho com código bastante trivial, além de alterar a implementação é muito mais barato, porque os testes são acoplados apenas à interface.

A cobertura total com testes de unidade de granulação fina tem uma enorme sobrecarga para alterar ou refatorar uma implementação, que é exatamente o que eles alegam facilitar.

yeoman
fonte