TDD ajuda a escrever programas mais simples?
Autor: Vinicius Assef | Publicado: 2016-11-07T10:39:00-02:00




Praticamente todo mundo que nunca tentou a abordagem Test First para escrever programas, pergunta: "Por que dizem que isso é melhor?"

Vou contar uma história real para você entender melhor.

Durante muito tempo eu desenvolvi software com a solução técnica em mente. Como todo principiante, eu ouvia o problema do cliente e logo começava a pensar nas tabelas, nos campos e nos relacionamentos que eu deveria implementar para resolver o problema. Em alguns casos eu pensava até nas funções e em alguns parâmetros que deveriam ser passados. Sempre eu resolvia o problema sob a **minha perspectiva**. O cliente recebia uma mera consequência da solução que eu oferecia. A visão técnica vinha primeiro. Vamos chamar essa abordagem "inside-out" (de dentro para fora).

Há alguns anos eu mudei a forma de desenvolver software. Hoje eu ouço o problema do cliente e direciono logo a conversa para "o que você gostaria de ver como resultado?". Pode ser uma funcionalidade de atualização, um relatório, uma consulta, uma mensagem de aviso na tela, um email. Eu foco logo na resposta que o sistema precisa entregar. Assim, eu começo a rabiscar em papel as colunas do relatório, o texto do email, a tela de resposta, etc. Pode ser que isso seja alterado até eu entregar a funcionalidade, mas eu já tenho o esqueleto da solução esperada. Talvez pareça ter mudado pouco, mas meu pensamento de desenvolvedor inverteu completamente! Agora, a solução sai sob a **perspectiva do cliente** que precisa ter seu problema resolvido. Acredite, fica muito melhor. Podemos chamar esse jeito diferente de abordagem "outside-in" (de fora para dentro).

Eu ainda penso em tabelas, campos e colunas. Foi assim que me ensinaram e foi assim que eu fiz por anos, mas evito pensar na solução técnica antes de fechar com o cliente o resultado esperado. Mesmo que os detalhes técnicos me venham à cabeça, eu me controlo e espero chegar o momento de me preocupar com eles.

Essa inversão na solução do problema nada mais é do que uma abordagem _Test First_. Primeiro eu entendo o problema. Em seguida eu verifico um resultado. Por último, eu penso no que preciso fazer (a solução) para atingir o resultado. Em alguns casos a solução técnica é tão simples quanto apresentar uma mensagem na tela. Em outros, pode ser que precise escrever um subsistema de enfileiramento de emails com envios assíncronos e controle de falhas.

Usando a nomenclatura de metodologias ágeis, quando eu foco primeiro no resultado, estou ajudando o cliente a especificar o **critério de pronto**, já com uma pré-validação técnica. Essa é uma das maiores dificuldades ao escrever uma _user story_. Aqui, nós fazemos isso juntos; o cliente e eu.

Quando escrevemos os testes primeiro, estamos colocando o resultado que esperamos em forma de código, mesmo antes de existir o programa. Eu foco na resposta que meu programa (ou função, ou método) precisa entregar. É como o rabisco do relatório em papel. É o meu critério de pronto. Pode ser que mude (e quase sempre muda) mas estou focado no critério de pronto.

Com meu critério de pronto escrito, eu consigo analisar se é simples ou complicado chamar essa rotina (função, método, módulo...) que eu nem escrevi ainda. Para conhecer a complexidade, eu faço perguntas como:

  - Estou passando muitos parâmetros para essa rotina?
  - É simples montar esses parâmetros?
  - O nome que estou dando a ela representa claramente o que ela deverá fazer?
  - A resposta que espero dela está simples de ser entendida e tratada nesse contexto?

Nessa etapa eu analiso o que eu vou desenvolver e faço o meu melhor para deixar a chamada e o retorno dessa rotina o mais simples possível. Essa é a parte do "outside". Cada uma dessas perguntas apontam para possíves problemas na elaboração da rotina. Por exemplo, se a lista de parâmetros é grande, talvez ela tenha muita responsabilidade e dividí-la em partes menores pode ajudar.

Depois do teste escrito com o critério de pronto eu já posso começar a escrever a solução; na parte "in". Eu já conheço os parâmetros que a rotina espera receber e o que ela precisará responder. Agora preciso codificar para entregar a resposta. Mas, será que vou precisar da ajuda de algum outro componente? Esse componente já existe? Se preciso criar esse componente ajudante, estou na parte "outside" dele e preciso escrever um (ou mais) teste(s) para ele. O ciclo recomeça a partir daí até que a resposta esperada pelo primeiro teste escrito seja atendida. Quando isso acontece, todos os componentes que precisaram juntar-se em uma força-tarefa já estarão mapeados, escritos e testados.

Não, não é mágica. É fruto de muito esforço e disciplina. Leva tempo. Você perde produtividade no início. Dá vontade de desistir um monte de vezes, mas evita problemas sérios. É como tentar escalar um paredão. Fincar os grampos, dar os nós corretos, prender nos lugares certos... Tudo isso adia o início da sua escalada. Nem é a escalada. Mas garante que você vai chegar lá em cima e conseguir voltar para casa. Sem esse procedimento de segurança você começaria a subir mais rápido, mas os riscos seriam altíssimos.

Finalizando, é por causa de todo esse processo que TDD ajuda a escrever programas mais simples e de forma mais segura. Porque você vai ter certeza de responder às perguntas certas. Nada mais; nada menos.