Programar é uma tarefa de criação bastante difícil, trabalhar com TDD mais cedo ajuda a reduzir a carga cognitiva que é grande. Por isso é tão importante evitar coisas como Task Switch, usar as técnicas certas e evitar distrações ao realizar uma tarefa.

Porém, existem técnicas de programação que podem te guiar ao longo do desenvolvimento. Uma delas é o TDD, mas não apenas isso, vamos entender um pouco melhor como usar os testes para aumentar a sua produtividade e trazer mais segurança no seu código.  

Definitivamente, porque o TDD é tão importante?

Se simplesmente considerar que TDD é Test-Driven Development por si só em suas palavras, você pode pensar que os testes podem ser realizados depois. Ainda mais quando você está começando na prática, ela tende a ser mais lenta mesmo.

Assim como é dito no artigo O que TDD não é, você pode considerar a sigla TDD como Test-Driven Design, ou seja, o TDD vai guiar a melhor construção do design do seu código, algo que você não vai conseguir com facilidade se implementar seus testes depois que o código foi feito.

Este é o ponto de virada em que vai fazer com que seu código leve a cumprir três das nossas regras de ouro:

Regra de ouro 1: Reduza ao máximo a complexidade

Regra de ouro 2: Eficácia vem antes de eficiência

Regra de ouro 4: Não negocie qualidade

Como garantir a melhor qualidade dos meus testes?

Existem algumas técnicas básicas que me ajudaram muito a desenvolver testes realmente eficientes:

FIRST

O ponto mais importante é seguir as seguintes regras durante a criação de cada caso de teste, seguindo elas você estará mais próximo de criar testes mais simples, estáveis e que realmente sejam assertivos quando encontrar algum tipo de problema. Eu falo mais a fundo sobre cada um destes pontos neste artigo, mas em resumo estes são os pontos principais:

(F)ast: Seus testes devem ser rápidos de serem executados

(I)solated: Nenhum teste pode depender de nada externo a ele (Ex.: Internet, variáveis globais, números aleatórios)

(R)epeatable: Não importa quando ou como seus testes são executados, eles devem ter sempre os mesmos resultados

(S)elf-Validating: No final da execução de toda a bateria de testes, deve ser muito fácil identificar se foi tudo um sucesso ou não e, em caso de falha, deve ser identificado o problema da forma mais simples possível

(T)horough: Seus testes devem exercitar o máximo de situações e pedaços do código possível

Code Coverage

Apesar de saber que cobertura de código pode se tornar uma métrica de vaidade, ela não deve ser ignorada. Quanto mais próximo de 100% melhor, mas isso não necessariamente mostra que os Unit Tests estão eficientes.

O que faço para escolher onde aumentar a cobertura é identificar quais as funcionalidades que são mais críticas, ou seja, mais utilizadas pelos clientes ou que gerem mais impacto caso elas deixem de funcionar e que tem um risco maior de quebrar por estar com baixa cobertura.

Por exemplo, dentro de um sistema de mercado a parte de controle do caixa da loja é com certeza mais importante do que os relatórios mensais de controle.

Apesar dos dois serem importantes, o fato do caixa estar parado gera um impacto negativo muito maior pois a loja ficará parada e não poderá faturar.

Mutation Testing

Esta ferramenta é uma recente novidade para mim e eu pretendo testar em alguns projetos. Ela basicamente atua fazendo a mutação do código, modificando ou removendo partes dele e executando os testes a cada mutação para verificar se algum deles irá quebrar.