Existem 5 passos num fluxo TDD:

  • Ler, entender e processar a feature ou bug.
  • Traduzir um requerimento escrevendo um unit test, se estiver usando um setup hot reloading, os testes vão falhar, visto que o código prioritário ainda não está implementado.
  • Escrever e implementar o código que satisfaz os requerimentos. Rodar os testes, eles devem passar. Se falharem, repetir o passo.
  • Limpar o código fazendo um refactor.
  • Aperfeiçoar o código.


O workflow acima é o conhecido RGR, ou Red-Green-Refactor, e suas fases significam:

  • Vermelho: Código não funciona.
  • Verde: Tudo funcionando, mas necessário otimizar.
  • Azul (Refactor): Tudo ok, podemos aplicar refatoramento e melhorar nosso código.

Unit tests também são parte integral do CI/CD e fazem parte do deployment pipeline, se os testes passarem, a integração e deploy acontecerá.

Ferramentas e libs

Como estamos usando Node, as libs:

  • Jest - para testes de unidade.
  • ESLint - para análise de código.
  • Standard - para formatação de código.
  • Husky - para hooks precommit de Git.

Decidindo quando escrever testes de unidade

Geralmente, existem dois casos onde queremos escrever os testes de unidade:
Caso 1: escrevemos um teste de unidade para representar uma funcionalidade concisa na nossa aplicação. Exemplo: uma funcionalide que retorna o numero de criptomoedas listados por determinada exchange. A primeira coisa a se fazer é escrever um unit test que falha, e depois escrever/mudar o nosso código até que ele passe nos testes.
Caso 2: um pedaço de código em prod quebra, o bug apresentado nesse código altera alguma funcionalidade da aplicação. Nesse caso, implementamos um teste de unidade e reescrevemos nossa funcionalidade até ela funcionar corretamente. Nesse caso teremos dois benefícios de implementar o unit test, a reusabilidade do teste e a correção do bug.

Conclusão

É essencial usarmos TDD nas nossas aplicações. TDD, embora aparentemente mais custoso de implementar no começo (aparentemente, pois evitar retestes ao implementar novas funcionalidades evita também muito tempo perdido) nos garante um código melhor, mais reutilizável e de mais fácil manutenção.