Testes de Unidade com TDD (Test Driven Development)

Pablo Rodrigo Darde
5 min readFeb 28, 2020

--

Este é a parte 1 de um série de 3 partes sobre Melhores Práticas em Testes de Unidade.

Você pode conferir as outras partes aqui:

Para desenvolver software com qualidade, além de uma boa arquitetura, é importante ter uma boa cobertura de testes, de preferência cobrindo toda a pirâmide de testes. A pirâmide de testes é uma abstração de uma automação de testes onde usamos a técnica de “dividir para conquistar” distribuindo diferentes responsabilidades para diferentes tipos de testes, testes de unidade, testes de integração, testes funcionais, e testes end-do-end. Todos estes testes são de extrema importância, no entanto, neste texto vamos focar apenas na base da pirâmide, os testes de unidade. Vamos usar a técnica TDD (Test Driven Development), ou, Desenvolvimento Guiado por Testes onde basicamente escrevemos o teste antes e o código para produção depois.

Testes de Unidade

Por que devemos escrever testes de unidade? Algumas das vantages de se escrever testes de unidade são:

  1. Diminuir a quantidade de bugs do sistema;
  2. Diminuir a necessidade de testes manuais;
  3. Desenvolver uma arquitetura mais eficiente;
  4. Facilitar o refactoring e aumentar a confiança.

TDD (Test Driven Development)

O TDD (Test Driven Development) foi desenvolvido na metodologia XP (Extreme Programming) por Kent Beck, um engenheiro de software signatário do Manifesto Ágil. Basicamente significa escrever nossos testes de unidade antes do código de produção. O TDD é a prática repetida de pequenos ciclos divididos em três fases: Red (failing test), Green (passing test), Blue (Refactoring).

Ciclo TDD: Red(Failing test), Green(Passing test), Blue(Refactoring)

Fase Red: escrever um teste que falhe.

Fase Green: escrever o mínimo possível para o teste passar.

Fase Blue: refatorar o código escrito.

Assim repetimos este ciclo inúmeras vezes para criar métodos, adicionar argumentos, retornos, comportamentos extras, etc… Nada deve ser escrito sem antes termos um teste falhando.

Um dos benefícios do TDD é fazer com que lidemos com pequenos pedaços de código de cada vez através de ciclos repetivivos de desenvolvimento. Desse modo é mais fácil manter o foco do que estamos fazendo e podemos avançar em pequenos passos controlados e na direção correta.

Para garantir que o fluxo está correto existem 3 leis para nos auxiliar. São as 3 leis do TDD. Essas leis nos forçam a escrever código escalável e desacoplado.

1ª Lei: Você não deve escreve nenhum código em produção sem antes ter um spec falhando.

2ª Lei: Você não pode escrever mais do que um teste de unidade para fazer seu spec falhar, e não copilar é falhar.

3ª Lei: Você não pode escrever mais do que o necessário para fazer o seu teste passar.

Prática!

Por exemplo, digamos que vamos criar um método que realize uma soma. Ao invés de criar o método diretamente para produção, primeiro nós criamos um teste para esse método. Vamos começar pela fase Red (criar um teste falhando).

Fase RED: App.test.js

Quando rodamos o teste podemos ver a mensagem “ReferenceError: sum is not defined”, pois o método “sum” ainda não existe.

Agora vamos para a fase Green (escrever o mínimo para nosso teste passar). Escrevemos o método sum.

Fase Green: App.js

E importamos o método sum no nosso teste.

Fase Green: App.test.js

O teste passou! Agora vamos para a fase Blue (Refatorar o código). Neste caso nosso método é bem simples então vamos apenas simplificar um pouco nossa função soma.

Fase Blue: App.js

Podemos ver que o teste continua passando. Este foi um ciclo completo de TDD onde escrevemos apenas o necessário para uma função soma.

Vantagens do Test Driven Development

  1. Tempo: Desenvolver com TDD diminui consideravelmente o tempo que perdemos com debugging, que hoje sabemos é onde perdemos a maior parte do tempo em desenvolvimento.
  2. Foco: Desenvolver em pequenos ciclos nos faz pensar em pequenos contextos, tornando nosso trabalho mais focado e mais controlado. Desenvolver em grandes ciclos é mais fácil de perder o controle e o foco do que queremos atingir.
  3. Cobertura: A partir do momento que não escrevemos nada em produção sem antes ter um teste falhando, nossa cobertura de testes cresce podendo facilmente chegar a 90%, 95% ou mais.
  4. Confiança: Com uma boa cobertura de testes bem escritos não temos receios nem medos na hora de mudar alguma coisa no código ou adicionar uma nova feature, pois sabemos que se algo sair errado nossos testes vão nos avisar.
  5. Documentação: Os testes também são ótimas fontes de documentação, pois specs e métodos bem escritos, seguindo padrões de clean code, podem ajudar a entender o que aquela parte do código faz.
  6. Desacoplamento: Desenvolvendo peças pequenas de software por vez, consequentemente estamos desenvolvendo código com baixo acoplamento, o que aumenta nossa escalabilidade.
  7. Disciplina: A prática do TDD nos trás disciplina no desenvolvimento diário. Ela nos permite trabalhar em uma pequena parte do código por vez independente do todo o resto do sistema. Isso aliado à técnica pomodoro faz nossa produtividade aumentar exponencialmente.
  8. Boa Arquitetrua: O TDD acaba moldando a arquitetura do nosso código de forma que ela fique menos acoplada e mais escalável.

Por fim TDD é um hábito do desenvolvedor e não tem nada a ver com regras da empresa. A responsabilidade de desenvolver software de qualidade, seguro e escalável é do desenvolvedor, e de mais ninguém. Seja você iniciante ou experiente, nunca é tarde para experimentar esse processo. Gostou do assunto? Aprenda mais sobre TDD e Testes de Unidade.

--

--

Pablo Rodrigo Darde

Software Engineer — bachelor’s degree in Software Engineering.