Embora seja consenso na comunidade de desenvolvimento que testes unitários são importantes, sua adoção ainda é restrita, muitas vezes por conta da pressão por prazos e pela dificuldade de explicar à equipe de negócios sua importância.

Os testes unitários costumam nos disciplinar a escrever códigos coesos e a nos dar segurança para alterações, minimizando as chances de quebrarmos o código já existente.

Robert C. Martin, em seu livro Código Limpo: Habilidades Práticas do Agile Software, afirma que “Os códigos de teste são tão importantes quanto os códigos que você utiliza em produção”. Ele afirma isto no contexto de sua experiência profissional, onde por vezes, teste unitários não foram adotados pela equipe ou foram feitos de forma descuidada, tornando-se muitas vezes um fardo para mantê-los funcionando. Desta forma, ele reforça a importância dos testes serem bem escritos, particionados, com variáveis e métodos bem descritivos e que rodem rapidamente para não atrasar o build do projeto.

Baseando-me na minha experiência profissional, vejo cenários onde a ausência de testes unitários pode ser justificada. Abaixo, listo alguns desses casos:

MVP (Produto Mínimo Viável)

Há casos, em que é necessário a criação de um produto de forma rápida. Startups costumam fazer isso muitas vezes para testar a aceitação do seu produto e verificar se vale a pena investir na ideia.  Eu participei de um projeto de desenvolvimento onde criamos um “Chat de Entrevistas” de forma extremamente rápida, pois precisávamos participar de uma concorrência para captar um cliente potencial.  Neste cenário, se eu tivesse adotado TDD, provavelmente não teríamos entregado um produto funcional a tempo. Posteriormente, optamos por descartar boa parte do código e construir algo um pouco mais estruturado e com testes, porém nessa etapa já tínhamos ganhado o cliente e estávamos com receita para investir mais no produto.

Códigos Legados

Há aplicações que são inviáveis escrever testes unitários depois que estão prontas. O código fonte não é modularizado para ser testado. Porém, se há prazo e consenso na equipe, refatorar e modularizar as partes que estão sendo alteradas e escrever testes unitários para elas podem ajudar na manutenibilidade do software no longo prazo.

Operações de CRUD com banco de dados

Já presenciei equipes que criavam testes para operações simples de DML no banco de dados. A maioria desses testes geralmente se certificavam de que a API de acesso a dados estava funcionando, algo que na prática já deveria ter sido testado pelos próprios criadores do framework. Acredito que os testes devam focar na lógica de negócio e se o código fonte da aplicação estiver bem estruturado, isolar e focar os testes na regra de negócio não será um problema. Em casos onde você vê extrema necessidade de fazer testes que envolvam um banco de dados, talvez você queira fazer um teste de integração, que por definição pode envolver várias partes do sistema.

Quando sua equipe não adota testes unitários

Esta parece óbvia, mas acontece com frequência. Se sua equipe não adota testes unitários, não adianta só você escrever os testes. Além do código provavelmente não estar estruturado para isso, outros membros da equipe simplesmente vão ignora-los. Já vi casos, de uma aplicação corporativa escrita em Java ter centenas de testes, porém no momento do build da aplicação, o comando maven estava assim: “mvn clean package -DskipTests=true”. Ou seja, todos aqueles testes escritos se tornaram inúteis e provavelmente não acompanharam a evolução do código de produção.

Portanto, em alguns casos me parece aceitável a não utilização de testes unitários. Cabe o bom senso do próprio desenvolvedor e da equipe para determinar quando os aplicar.