É “Test-Driven Design” e não “Design Done by Tests”

Muitos códigos legados possuem graves problemas de design. Classes gigantes que fazem tudo ou classes altamente acopladas são exemplos reais de código presentes no dia-a-dia de muitos desenvolvedores. E isso não é uma exceção: as leis da evolução do software mostram que o código de um software tende a degradar. O trabalho do programador é evitar que isso aconteça ou, no pior caso, diminuir a velocidade desse processo de apodrecimento do design.

A busca por um design perfeito, que esteja preparado para aceitar mudanças e evoluir de forma simples, é difícil. Por esse motivo, a prática de TDD tem sido muito comentada pois, segundo seus praticantes, ela ajuda o programador a criar um design melhor.

Mas, a mais famosa frase da área de engenharia de software já nos diz que não existe bala de prata. Nenhuma prática garante o sucesso de um projeto ou um código de qualidade. As práticas estão lá para tentar manter o programador nessa direção.

E é a mesma coisa com TDD: a prática não resolverá todos os problemas de design que um programador enfrentará. O programador, na verdade, utiliza os testes para guiar o design. É através dele que o programador sabe se está indo no caminho certo ou não. Isso não quer dizer que TDD faz o design sozinho para o programador. É óbvio que o programador precisa ter experiência e conhecimento necessários para que o design saia realmente com qualidade.

Mas um programador que tenha alto conhecimento e experiência em desenvolvimento também pode criar um design com a mesma qualidade. A diferença é que TDD (e os testes gerados) dão feedback muito mais rápido sobre a qualidade. O gráfico abaixo, feito pelo Gleen Vanderburg, mostra o tempo de feedback de várias práticas ágeis. Veja que TDD dá feedback em minutos, ou seja, em alguns minutos o programador tem informações sobre o seu design. Através dos testes ele pode obter informações como a coesão da classe, o acoplamento, a simplicidade, etc. Novamente, o programador usa sua experiência para receber e entender esse feedback.

Figura 1. Práticas e tempo de feedback

Essa é na verdade a grande diferença para o design feito pelo arquiteto-astronauta, famoso no modelo Waterfall, para os designs ágeis. O arquiteto pode ter muita experiência, mas o design que ele faz leva tanto tempo para ser validado e receber feedback que, quando isso acontece, o custo de mudança é altíssimo.

Além disso, o programador ao usar TDD (e por consequência guiar seu design através dos testes) é “forçado” a utilizar bons princípios de orientação a objetos. Os tão falados princípios SOLID passam a fazer mais sentido no momento em que o programador precisa escrever um código que seja fácil de testar. Parafraseando Feathers, existe uma grande sinergia entre código fácil de testar e código bom. Esses bons padrões facilitam o programador a escrever um código mais fácil de testar, apesar do Mark Seemann discordar.

Novamente, a experiência do programador conta. O programador experiente sabe que deve gerenciar as dependências entre classes (DIP), sabe que as classes devem ser coesas (SRP), sabe que elas devem evoluir sem a necessidade de reescrevê-la (OCP), e etc. Programadores que não usam TDD também podem fazer uso desses bons princípios. A diferença é que TDD dá feedback quase instantâneo: a necessidade da utilização dessas ideias aparece após alguns minutos programando, o que não é verdade quando o programador não faz TDD.

Enfim, TDD não faz milagre. Mas ele fica lembrando o programador constantemente sobre a necessidade de manter o código limpo. E a necessidade disso é evidente. Com certeza outros programadores irão encontrar outras práticas que também dão feedback sobre qualidade de design ao desenvolvedor. Mas, enquanto isso não acontece, eu recomendo a utilização de TDD.

Mas lembre-se: é design guiado pelos testes (Test-Driven Design) e não design feito pelos testes!

8 thoughts on “É “Test-Driven Design” e não “Design Done by Tests”

  1. Rafael Miranda

    Muito bom artigo! Parabéns.

    Estamos começando um novo projeto relativamente grande (estimativa de pelo menos 1 ano para conclusão), e infelizmente o TDD ainda está sendo “questionado” pela gerência e por vários integrantes da equipe. Questionamentos básicos: aumento do tempo do projeto (gerência) e prática desconhecida e estranha (parte da equipe).

    Lamentável… Mas aos poucos iremos conseguir. Estou compilando vários dos seus textos e apresentações para tentar desmistificar algumas coisas com a equipe.

    Parabéns novamente pelo conteúdo que vc produz.

    Reply
  2. Caio Rodrigues

    Alguém aqui já teve alguma conclusão sobre o uso de TDD em aplicações consideradas “extensas”, como um CRM ou um ERP onde precisamos muito utilizar “reusabilidade de código”?

    São aplicações que podem crescer dinamicamente dependendo do cliente.

    Reply
  3. Jhonatan Fernando

    Olá Maurício, muito bom o post parabéns. No primeiro parágrafo você mencionou uma realidade muito presente. Classes que fazem mihões de coisas, métodos gigantes e designer inexistente.Na minha realidade existem coisas antigas assim já as novas implementações já está dando tempo de pensar mais e aplicar boas tecnologias. Sobre as antigas, você acha interessante um dia parar tudo e refazer ou ir refazendo a medida que aparece manutenção nessa parte do código? Obrigado.

    Reply
  4. Gustavo Henrique

    É verdade que TDD não é uma bala de prata, mas quase chega lá. TDD não é uma atividade facilmente mensurável pois a experiência do programador também influência na escrita dos testes.
    Uma das grandes vantagens do TDD é que os testes acabam sendo como um documento sobre o funcionamento de uma classe. Com isso a manuntenabilidade do sistema fica mais fácil e se um novo desenvolvedor entrar na equipe, a curva de aprendizado sobre o funcionamento do sistema vai ser menor. Isso, claro, se os testes estiverem bem escritos.
    Quem trabalha bem com metodologias ágeis consigue entregar um software em menos tempo, com menos bugs (a maioria dos bugs é mais sobre o entendimento do negócio) e a manutenção é mais light. Recomendo fortemente!

    Reply
  5. Daniel Tamiosso

    Cara,

    Muito didática a abordagem da relação das práticas e o tempo de feedback.

    Realmente esse pensamento “faça TDD e tudo vai ficar lindo” é enganoso. Com certeza a prátca vai encorajar o desenvolvedor a lidar com vários questionamentos – o tempo todo. E muitos desses relacionados ao design. O que vai valer, no fim, é a atitude e o conhecimento concentrados nos feedbacks recebidos.

    Demais, muito bom e útil o post.

    Reply
  6. mauricioaniche Post author

    @Rafael Miranda,

    Muito legal! Se precisar de ajuda para convencer alguém, é só falar! 🙂

    @Jhonatan,

    Nem sempre é possível jogar código fora e refazer tudo. É economicamente inviável! Meu conselho é ir refatorando a medida que você passar por aqueles pontos.

    @Caio,

    Eu já participei de grandes projetos onde usamos TDD, e pode lhe dizer que a prática fez grande diferença. Mexer em código produzido com TDD é mais fácil (experiência própria).

    @Gustavo,

    Sim, TDD tem diversas vantagens! Difícil argumentar só de uma, pois cada desenvolvedor tem o seu lado favorito da prática! O meu? Efeito dele no design! 🙂

    @Daniel,

    Concordo! Experiência faz sim diferença!

    Reply
  7. Pingback: O melhor da semana 23/01 a 29/01 « QualidadeBR

  8. Pingback: Fazendo as pazes com TDD (Test-Driven Development) | Eric Lemes' Blog

Leave a Reply

Your email address will not be published. Required fields are marked *