É bastante aceito que um software bem testado, sobretudo de maneira automatizada, é bem mais robusto.Quanto maior o software, mis difícil de trabalhar com ele. Existem várias formas de deixar a vida mais fácil, mas usar testes, como os unitários, é uma maneira bem segura de construir sistemas com qualidade.
Com o advento dos assistentes de código, cada vez mais, o trabalho de escrever algoritmos, escrever código no geral, vem se tornando uma tarefa da IA. A gente pede, como quem pede uma coca-cola, e o assistente automatiza um monte de tarefas até entregar um código bastante funcional. A IA fica com boa parte das tarefas chatas. Mas a gente continua com a parte difícil: verificar se o que foi construído atende aos requisitos e realmente fuciona.
Mas quem vigia os vigilantes? Imagine uma base de software legado que não foi construída pela IA. Imagine que esse software tem bastante qualidade, segue as boas práticas e é bem testado que com várias ferramentas. Do nada, a IA começa a trabalhar nesse código. Hoje em dia, não há muitos motivos válidos para não deixar ela trabalhar nesse código. Se a gente passar algumas instruções do tipo “não mexa nos testes que já estão funcionando a menos que explicitamente solicitado”, ela não vai mexer. E melhor, ela também consegue garantir que qualquer alteração nas regras serão feitas com objetivo de não quebrar os testes. A IA é uma espécie de dev junior em início de carreira, cheio de gás para trabalhar e com poder enorme de ler a documentação.
Mas e o código novo, as novas funcionalidades, as coisas criadas do zero? Se a gente pede um cálculo de imposto com taxa de 10% e a IA cria uma código com uma taxa de 0.1%, ela vai fazer um teste que garante esse comportamento, mesmo que ele esteja errado. Por isso nós continuamos com o trabalho difícil. A argumentação de que a IA errou por falta de um prompt mais direcionado é totalmente válida, mas somos nós que damos esse prompt. A responsabilidade é sempre nossa. Nós escrevemos “rules”, “skills”, “memory bank”, “plans”, “specs” e qualquer outra técnica da moda nos tempos da IA.
Nesse sentido, qual o papel dos testes unitários nos dias atuais? Na minha visão, os testes unitários continuam tendo um papel central, talvez até mais importante do que antes. A diferença é que agora eles não servem apenas para proteger o código contra outros desenvolvedores humanos. Eles também servem para proteger o sistema contra a própria velocidade da IA.
Antes, a gente tinha um desenvolvedor escrevendo uma funcionalidade, errando, corrigindo, testando, abrindo PR, recebendo review. Esse processo era mais lento. Hoje, uma IA consegue gerar em poucos segundos uma quantidade enorme de código que talvez um humano levaria horas ou dias para escrever. Isso é muito bom, mas também muda a natureza do problema. O risco não é mais apenas escrever código errado. O risco é escrever muito código errado muito rápido, com uma aparência muito convincente.
É aqui que os testes entram como uma espécie de contrato executável do sistema. Eles dizem para a IA: “você pode mexer, pode refatorar, pode melhorar, pode criar coisas novas, mas esse comportamento aqui não pode ser quebrado”. Em sistemas grandes, isso é essencial, porque ninguém consegue guardar na cabeça todas as regras, todos os casos especiais, todas as decisões históricas e todos os bugs que já foram corrigidos.
Um teste bem escrito é mais do que uma verificação técnica. Ele é a memória viva do sistema. Ele guarda um pedaço do conhecimento do sistema. Quando um bug é corrigido e vira teste, aquele bug deixa de ser apenas uma lembrança na cabeça de alguém e passa a ser uma proteção automática. Quando uma regra de negócio vira teste, ela deixa de estar apenas em uma conversa, em uma issue ou em uma documentação esquecida, e passa a ser algo que roda toda vez que o sistema muda.
Nesse sentido, os testes unitários ajudam muito a IA porque dão limites claros. A IA pode até não entender completamente o domínio, mas ela consegue entender que um teste falhou. Ela consegue ler o erro, procurar a causa e propor uma correção. Isso cria um ciclo de feedback muito poderoso: a IA escreve, executa, observa, corrige e tenta de novo. Quanto melhor for a suíte de testes, melhor fica esse ciclo.
Mas existe uma armadilha. Não basta ter teste. É preciso ter teste bom. Cobertura de teste, sozinha, pode enganar. Um projeto pode ter 90% de cobertura e ainda assim ter testes fracos, cheios de mocks inúteis, asserts genéricos e cenários que apenas confirmam que o código executa sem explodir. Cobertura mostra que uma linha foi executada, mas não prova que aquela linha foi validada corretamente. No mundo da IA, esse problema fica ainda maior, porque é muito fácil pedir para ela “criar testes para aumentar cobertura” e receber uma bateria enorme de testes que não protegem quase nada. A IA pode gerar teste para comportamentos já errados que ela mesma criou e que a gente não validou.
Por isso, talvez a pergunta mais importante não seja: “quantos por cento de cobertura temos?” Mas sim: “os testes falham quando a regra é quebrada?”. Um bom teste precisa ter força. Ele precisa incomodar quando alguém muda o comportamento errado. Ele precisa acusar quando uma regra deixa de ser respeitada. Ele precisa proteger o sistema contra regressões reais. Se a IA altera um cálculo de imposto, uma regra de autorização, uma validação qualquer, os testes precisam gritar.
E quando um teste existente falha, a IA não deveria simplesmente sair alterando o teste para ficar verde. Esse talvez seja um dos pontos mais importantes. Teste vermelho não é um obstáculo a ser removido. Teste vermelho é uma pergunta sobre o que você mudou com esse comportamento foi de propósito ou quebrou alguma coisa.
Em um ambiente profissional, a IA deveria ser instruída a tratar testes existentes como uma fonte de verdade, salvo quando houver uma decisão explícita de mudança. Se o teste falhou, primeiro ela precisa explicar por que falhou. Depois, precisa dizer se a implementação está errada ou se o teste representa um comportamento antigo que realmente deve mudar. Só então alguém decide se o teste deve ser atualizado.
Isso preserva uma coisa muito importante: a autoridade dos testes antigos. Muitas vezes, aquele teste estranho, com um caso específico, existe porque um dia a produção caiu, um cliente reclamou, uma integração quebrou ou uma regra obscura precisou ser respeitada. Apagar ou alterar isso sem entender é perigoso.
Já para código novo, o cuidado é outro. A IA pode escrever o código e também pode escrever os testes, mas a expectativa do teste precisa vir de algum lugar confiável. Pode vir de uma regra de negócio, de um contrato de API, de uma documentação oficial, de um exemplo dado por um especialista, de uma issue bem escrita, de um caso real de produção ou de uma decisão explícita do time. O que não dá é deixar código, teste e expectativa nascerem todos da mesma alucinação.
Se eu peço para a IA implementar uma regra e ela entende errado, ela provavelmente vai implementar errado e testar errado. O teste vai passar, o pipeline vai ficar verde, o relatório de cobertura vai sorrir para todo mundo, mas o sistema vai estar errado. Por isso, a parte difícil continua sendo nossa: definir corretamente o comportamento esperado.
A IA pode automatizar a escrita. Pode automatizar a criação de cenários. Pode automatizar fixtures, builders, mocks, massas de dados, testes parametrizados, casos de borda e até ajudar na leitura de falhas. Mas ela não pode assumir sozinha o papel de dona da verdade. A verdade do sistema vem do domínio e de quem conhece ele.
É por isso que testes unitários continuam sendo fundamentais, mas precisam ser combinados com outras práticas. Testes unitários são ótimos para verificar regras pequenas, funções, classes e decisões isoladas. Mas eles não substituem testes de integração, testes de contrato, testes end-to-end, testes de regressão, análise estática, revisão de código, validação humana e, em muitos casos, testes de mutação.
Testes de mutação, por exemplo, se torna muito interessante nesse cenário. A ideia é simples: a ferramenta modifica pequenos pedaços do código de propósito. Troca um > por >=, um true por false, remove uma condição, muda uma operação. Se os testes continuam passando, talvez eles não estejam verificando o comportamento com força suficiente. Isso ajuda a responder uma pergunta que cobertura comum não responde: “meus testes realmente detectam defeitos?”.
No contexto de IA, isso é muito relevante. Porque a IA pode gerar muitos testes bonitos, organizados e aparentemente completos. Mas se pequenas mutações no código não quebram esses testes, eles são frágeis. Eles estão ali mais para satisfazer uma métrica do que para proteger o sistema.
Então, talvez o papel moderno dos testes unitários seja deixar de ser apenas uma boa prática de engenharia e passam a ser uma infraestrutura de governança sobre o trabalho automatizado da IA. Um nova profissão, Governança de IA? Os testes são uma cerca. Eles são um contrato. Eles são uma memória. Eles são um freio. Eles são também um acelerador, porque quanto mais confiança a gente tem nos testes, mais liberdade a gente tem para deixar a IA trabalhar.
Em sistemas pequenos, talvez seja possível revisar tudo no olho. Em sistemas grandes, isso é ilusão. Uma mudança aparentemente local pode afetar regras distantes, integrações antigas, formatos de dados, permissões, eventos, mensagens, cálculos e comportamentos que ninguém lembrava mais. A IA consegue ler muito código, mas não necessariamente entende as consequências sociais, históricas e negociais daquele código. Os testes ajudam a transformar parte desse conhecimento em algo verificável.
No fim, eu acho que a IA não diminui a importância dos testes. Ela aumenta. Porque se a velocidade de produção aumenta, a necessidade de controle também aumenta. Se o código passa a ser gerado com mais facilidade, a validação precisa ser mais forte. Se o assistente consegue criar uma funcionalidade em minutos, o sistema precisa ter mecanismos para dizer se aquela funcionalidade respeita o que já existia.
A grande mudança talvez seja cultural. Antes, a gente escrevia testes para proteger o código contra mudanças futuras. Agora, a gente (digo, a IA) também escreve testes para orientar agentes automáticos (ela mesma) no presente.
A IA pode ser uma programadora incansável, rápida, obediente e muito útil. Mas ela precisa de trilhos. Testes unitários bons são parte desses trilhos. Sem eles, a IA vira uma máquina de gerar confiança falsa. Com eles, ela pode virar uma das maiores ferramentas de evolução segura de software que a gente já teve.