Eu comecei a aprender TDD no final da minha graduação e eu já venho aplicando essa metodologia a mais de 4 anos. Atualmente acredito que tenho um bom conhecimento do que funciona e o que não funciona nessa prática. Assim, o objetivo desse post é explicar o porquê eu acredito que a maioria dos devs não estão valorizando tanto esta prática quanto deveriam.
Como já é conhecido, a metodologia do TDD funciona com base em três etapas:
- Desenvolvimento dos testes (red);
- Implementação do código (green);
- E por último, refatoração do código (refactor).
Para quem está iniciando no TDD é difícil pensar em criar os testes primeiro para depois fazer a implementação do código. Por isso, existem práticas iniciais que todo dev precisa passar para começar a aplicar a metodologia na sua forma plena.
Um dos principais problemas que vejo que dificultam o aprendizado, é quando os iniciantes em testes decidem aprender a testar enquanto aprendem a metodologia. Veja, a metodologia é sobre testes, então se você está aprendendo a testar enquanto aprende TDD será muito mais difícil.
Pra mim, hoje é muito tranquilo criar os testes primeiro e desenvolver as funcionalidades depois, com um tempo, o processo se tornou muito automático e produtivo. Mas, para quem está iniciando não é exatamente a forma de bolo mostrada na imagem acima.
Às vezes por conta da dificuldade de entendimento, seja de um requisito ou de alguma ferramenta, será necessário escrever um pouco de código antes para poder entender como testá-lo. E outras vezes, o código já estará bom o suficiente e não precisará de refatoração.
Outra coisa que dificulta o emprego dessa metodologia, é o mito de que o TDD não funciona em ambiente profissional, somente no ambiente acadêmico. Por conta disso, na pressão diária da entrega das tarefas, a maioria dos devs não conseguem praticar o suficiente para se acostumarem a escrever os testes primeiro.
Existem também as justificativas com relação a falta de produtividade na escrita dos testes ou o aumento do tempo de entrega das tarefas. Nesses casos, vejo dois cenários recorrentes:
1. Os devs não possuem experiência necessária com testes automatizados;
2. Os testes são feitos depois que o código foi testado manualmente.
O primeiro cenário é o principal, quando o dev não entende como fazer os testes, consequentemente o dev não se sentirá produtivo. No segundo caso, é óbvio que a tarefa irá demorar, já que o tempo de desenvolvimento é somado ao tempo de testes manuais, junto com o tempo de implementação dos testes automatizados.
Por sempre utilizar essa metodologia, eu nunca sofri tanto com a falta de tempo. Confesso que hoje é até difícil pra mim desenvolver software sem testes (eu me sinto muito improdutivo). Então, essa é uma das principais vantagens do TDD. Por está desenvolvendo os testes junto com a funcionalidade, eu nunca vou fazer a implementação dos testes depois, eu sempre irei desenvolvê-los enquanto implemento a tarefa. Assim eu consigo pegar os erros antes e corrigi-los. Com isso, a entrega será muito mais rápida do que antes, e na minha opinião, se o objetivo for sempre criar os testes depois, os testes acabam se tornando mais uma obrigação, como por exemplo, a criação de documentações técnicas.
Além desse ponto, existem várias outras vantagens em desenvolver testes com TDD, são elas:
- Melhorar o entendimento sobre os requisitos: Quando você está desenvolvendo com testes, você precisará entender muito bem a funcionalidade para poder implementá-los. Com isso, a metodologia te obriga a buscar mais informações.
- Qualidade do código: Por conta das etapas de testes e refatoração, o resultado é um código bem arquitetado com um bom design. Isso contribui para as três principais qualidades de um bom software (testability, evolvability and maintainability).
- Nível de Coverage: Por está sempre aplicando testes nas funcionalidades, consequentemente o código terá um nível alto de coverage. Níveis altos de coverage irão diminuir a quantidade de bugs em ambiente de produção ou até mesmo mitigá-los.
Por fim, a produtividade com testes se mostra quando você adquire um certo nível de proficiência no desenvolvimento de testes. A partir daí cada teste que for desenvolvido se torna meio que um item em um ToDo list. Dessa forma, a medida que as funcionalidades forem sendo implementadas, o ToDo list será aos poucos completado.