A efetividade real de TDD não está no fato de escrever o teste antes do código (segundo Tio Bob)
Tags: tdd
Published: 2020-07-22 11:27:35

_This post is also available in [English](https://dev.to/toureh/the-really-effective-part-of-tdd-is-not-so-much-whether-you-write-the-test-first-according-to-uncle-bob-3h6n)._

---

Tente imaginar como esta frase do Robert C. Martin termina:

"_The really effective part of TDD is_ ..."

Robert C. Martin, (carinhosamente conhecido como Tio Bob) é autor do livro clássico [Código Limpo](https://www.amazon.com/C%C3%B3digo-Habilidades-Pr%C3%A1ticas-Softwar-Portuguese/dp/8576082675), um dos autores originais do Manifesto Agile e um [defensor ferrenho](https://www.youtube.com/results?search_query=uncle+bob+tdd) da prática de [TDD](https://martinfowler.com/bliki/TestDrivenDevelopment.html)  como uma ferramenta para aumentar a produtividade de desenvolvedores e a qualidade do código produzido por eles.

Recentemente li um post (antigo) no blog do Tio Bob no qual ele afirma que a efetividade real de TDD **não está** no fato de escrever o teste antes do código de produção e confesso que fiquei um tanto quanto ... chocado.

Esta afirmação me chamou muito atenção porque o evangelismo do Tio Bob a favor de TDD é implacável. Tão implacável que ele já foi capaz de [afirmar](https://youtu.be/GvAzrC6-spQ?t=23) que escrever testes depois de escrever código de produção é um desperdício de tempo. 😱

Então, qual fator poderia ser tão importante para a prática de TDD ao ponto do Tio Bob considerá-lo mais importante que a relação de ordem entre a criação de testes e a criação do código de produção?

A resposta repousa na história das famosas 3 Leis de TDD. Você provavelmente já ouviu essas 3 leis ou pelo menos alguma versão delas:

* Não é permitido escrever código de produção a não ser que seja para fazer passar um teste que esteja falhando.
* Não é permitido escrever mais do teste do que seja necessário para fazer o teste falhar, ou deixar de compilar.
* Não é permitido escrever mais código de produção do que o suficiente para fazer um teste passar.

Em [outro post](https://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html) no seu blog, intitulado "Os Ciclos de TDD", o Tio Bob conta como as 3 leis se originaram enquanto relata uma experiência que teve quando pareou com Kent Beck, **o criador da metodologia Extreme programming (XP) e da prática de TDD**!

---

"_Eu me sentei para parear com Kent Beck em 1999 para aprender. De fato ele me ensinou a escrever os testes primeiro, mas em um processo mais granular do que eu já tinha visto antes. Ele escreveria **uma linha de teste** que falharia e então escreveria **uma linha de código de produção** correspondente para fazer o teste passar. Às vezes era um pouco mais de uma linha, mas a escala que ele utilizava era muito próximo de linha a linha_.

....

_O objetivo de escrever sobre as 3 leis sempre foi promover essa granularidade **linha a linha** que eu experimentei enquanto trabalhava com Kent._” (Tradução livre)

----

Não sei se a frase acima teve o mesmo impacto revelador em você que teve em mim quando a li pela primeira vez. _But, I was mind blown._

![Mind blown](https://media.giphy.com/media/msriR5ybSpQgo/giphy.gif)

Quando comecei a tentar fazer TDD, eu achava que só estaria fazendo TDD de verdade se eu terminasse de escrever todos os testes da funcionalidade que eu iria implementar, antes de encostar no código de produção.

Eu atribuo esta linha de pensamento ao fato de eu praticar apenas [Test-last Development](http://xunitpatterns.com/test%20last%20development.html) (TLD), antes de me aventurar no mundo de TDD. Ou seja, eu implementava uma funcionalidade e depois de estar satisfeito com os resultados de testes exploratórios, eu então escrevia testes automatizados. Na minha cabeça TDD seria apenas uma inversão desta ordem.

Resultado: A ideia de escrever testes antes de escrever código de produção me parecia pouco intuitivo (e me apavorava). Também não via (e continuo não vendo) praticidade em tentar completar um conjunto de testes sem IntelliSense e com quase todas as linhas sublinhadas de vermelho pelo IDE pelo fato dos métodos e propriedades da classe a ser implementada não existirem ainda. 

Ao me aprofundar no estudo sobre o tema, encontrei várias fontes que frisam o fato de que a prática de TDD é fundamentada em repetições de **pequenos ciclos** de teste e desenvolvimento. Por exemplo, no livro [The Art of Agile Development](https://www.jamesshore.com/Agile-Book/test_driven_development.html), (leitura [indicada pelo Martin Fowler](https://martinfowler.com/bliki/TestDrivenDevelopment.html)), o James Shore recomenda trabalhar em ciclos de teste e desenvolvimento que não passam de 5 minutos ou de 5 linhas de código.

Se você estiver se perguntando como isso funciona na prática, recomendo 2 vídeos:
[Tutorial: Mastering Test-Driven Development with Angular](https://youtu.be/JOYNHkRN_YY) e 
[este trecho do vídeo The Three Laws of TDD](https://www.youtube.com/watch?v=AoIfc5NwRks&t=1450s)

Com esta realização, eu voltei a praticar TDD, seguindo as 3 leis à risca na maior parte do tempo e hoje o processo tem se tornado muito mais intuitivo e **rápido**. 😃

Para finalizar, vamos voltar àquela frase incompleta do início deste post e o momento em que o Tio Bob é pego com a boca na botija, flagrado, afirmando que a efetividade real de TDD não está no fato de escrever o teste antes do código de produção. 👀

Eu encontrei a afirmação em [outro post](https://blog.cleancoder.com/uncle-bob/2016/11/10/TDD-Doesnt-work.html) do seu blog no qual o ele analisa um estudo que conclui que a prática de TDD não tem um impacto significativo sobre a qualidade do software produzido por equipes.

Aconselho fortemente ler [o post](https://blog.cleancoder.com/uncle-bob/2016/11/10/TDD-Doesnt-work.html) na sua integridade para entender **o contexto** da afirmação, mas para resumir o estudo: 58 desenvolvedores foram divididos em 2 grupos para realizar alguns desafios de programação. Um grupo deveria fazer TDD enquanto o outro grupo fizesse TLD (Test-last development). Os 2 grupos foram orientados a trabalhar em **pequenos ciclos** de desenvolvimento e testes e não de uma forma cascata. No final, métricas foram comparadas e o estudo conclui que TDD não tem efeito (nem positivo, nem negativo) sobre a produtividade dos desenvolvedores nem sobre a qualidade do código produzido.

Então, porque raios a gente deveria escrever testes **antes** do código de produção?

Em resposta a este estudo, o Tio Bob destaca o fato que tanto os devs do grupo de TDD quanto os do grupo de TLD trabalharam em pequenos ciclos e afirma:

"_A efetividade real de TDD está no tamanho do ciclo, e não no fato de escrever o teste antes. **Escrevemos testes antes porque isso nos motiva a manter os ciclos muito pequenos**._" (Tradução livre)

_Texto original:_
_"The really effective part of TDD is the size of the cycle, not so much whether you write the test first. The reason we write the tests first is that it encourages us to keep the cycles really short."_

Wow!

Obrigado por ler até o final (ou por pular para o final só para ver a resposta). Espero que o post tenha sido enriquecedor para você!