Pular para o conteúdo
ARCHYSIUM
← Blog

Testes automatizados na era da IA: velocidade sem confiança é apenas risco em escala

Na era do desenvolvimento assistido por IA, gerar código ficou mais rápido. Entenda por que testes automatizados são essenciais para transformar velocidade em confiança.

Leandro Lima
Leandro Lima · 14 de outubro de 2026 · 13 min de leitura
processo qualidade
Ilustração escura mostrando código gerado por IA fluindo para uma lista de verificações em verde, convergindo num escudo brilhante com um check, simbolizando testes transformando velocidade em confiança

Antigamente, um cenário comum nas empresas de desenvolvimento de software era o alto custo de tempo para escrever testes automatizados. Por um lado, eles garantiam que o comportamento do sistema correspondia ao esperado, desde que a regra de negócio tivesse sido implementada corretamente. Por outro, demoravam bastante pra escrever, o que acabava determinando se a aplicação teria ou não uma boa cobertura. Desses testes, os de unidade sempre foram os de maior quantidade e maior valor.

Entretanto, na era atual, ferramentas de inteligência artificial estão mudando todo esse processo e como software é desenvolvido. Hoje, um desenvolvedor pode receber testes para uma funcionalidade em poucos segundos, incluindo testes de integração e testes e2e, tornando facilmente a cobertura de testes na casa dos 80%. A coisa ficou realmente simples. Agentes conseguem navegar por uma base de código, criar arquivos, alterar APIs, refatorar módulos, implementar o que for em pouquíssimo tempo, reduzindo drasticamente o custo de produzir código.

Mas aí que tá o negócio. Tem uma diferença absurda entre produzir código rapidamente e produzir software confiável, pois maior velocidade no desenvolvimento não quer dizer qualidade, e também pode aumentar as chances de introduzirmos comportamentos incorretos no software. Com tudo isso, é importante entender que já não se trata apenas de uma prática tradicional de qualidade, mas que os testes passam a funcionar como um dos principais mecanismos de feedback e verificação para o desenvolvimento assistido por IA.

Mas antes de prosseguirmos no contexto atual de desenvolvimento de software, precisamos voltar no tempo e entender um contexto maior sobre o assunto de testes automatizados.

Testar não significa provar que o software está correto

Em 1969, na conferência NATO, uma conferência para decidir os rumos da área de software, Edsger W. Dijkstra fez uma observação que se tornaria uma das frases mais conhecidas da área:

“Testing shows the presence, not the absence of bugs.”

Em tradução livre:

“Testes mostram a presença, não a ausência de bugs”.

A frase aparece nos proceedings da conferência Software Engineering Techniques, no contexto de uma discussão sobre os limites dos testes.

Mais de meio século depois, essa distinção continua fundamental.

Vamos a um exemplo. Imagine uma função simples:

function calculateDiscount(total: number) {
    if (total >= 1000) {
        return total * 0.9
    }

    return total
}

Podemos escrever dezenas de testes para ela. Se todos passarem, sabemos que determinados comportamentos foram verificados.

Mas isso não demonstra matematicamente que nenhum caso incorreto existe.

Pode haver uma regra de negócio que esquecemos. Um caso de borda que não imaginamos. Uma interpretação incorreta do requisito. Ou simplesmente podemos ter escrito um teste que confirma a mesma suposição errada presente na implementação.

Isso sempre foi verdade.

Com IA, porém, surge uma consequência interessante: a IA também pode gerar implementação e teste baseados na mesma interpretação incorreta.

Diagrama: requisito ambíguo vai pra IA, que gera código errado e teste errado a partir da mesma interpretação, e os dois convergem num falso "Test passes"

Quando a IA interpreta o requisito errado, o erro se propaga tanto pro código quanto pro teste — o resultado é um “passou” que não significa nada.

Um teste verde continua significando apenas que o comportamento observado corresponde ao comportamento esperado pelo teste. Não significa necessariamente que construímos o comportamento correto. Se a implementação da regra de negócio estiver incorreta, e o teste testar essa regra, então, o comportamento estará errado mesmo que o teste tenha passado.

Essa é uma razão para testes não substituírem revisão (seja humana ou por IA), entendimento do domínio, critérios de aceitação e validação do produto — independentemente de quem escreveu o código.

Testes como uma rede de segurança

Além de Dijkstra, outra figura importante na área de computação é Michael Feathers. Autor de Working Effectively with Legacy Code, ele apresenta em seu livro (2004) uma definição propositalmente provocativa:

“To me, legacy code is simply code without tests.”

Em português:

“Para mim, código legado é simplesmente código sem testes”.

A preocupação de Feathers não era simplesmente o código legado, mas sim de que sem testes não conseguimos determinar rapidamente se uma mudança preservou comportamentos importantes.

Essa ideia talvez tenha se tornado ainda mais relevante com desenvolvimento assistido por IA.

Antes, uma alteração relativamente grande poderia exigir horas de trabalho manual. Agora podemos pedir:

Refatore este módulo para separar as regras de negócio da infraestrutura.

Ou:

Migre esta implementação para utilizar outro ORM sem alterar o comportamento da API.

Um agente pode modificar dezenas de arquivos. Com tudo isso, o problema passa a ser menos: “Quanto tempo levará para escrever essa mudança?” e cada vez mais: “Como sabemos que essa mudança continua correta?”

E é aí que uma suíte de testes funciona como uma rede de segurança.

Fluxo: uma mudança passa por "Código + IA", depois por testes automatizados, que resultam em confiança quando passam ou em feedback imediato quando falham

A IA pode aumentar enormemente a quantidade de mudanças que conseguimos realizar. Os testes ajudam a aumentar proporcionalmente nossa capacidade de verificá-las.

Esse talvez seja um dos maiores ativos dos testes no contexto atual: eles garantem que as expectativas humanas sobre o sistema sejam comprovadas através dos testes executáveis.

A pirâmide de testes ainda faz sentido?

Em Succeeding with Agile, Mike Cohn popularizou a Test Automation Pyramid. A ideia original divide a estratégia em três níveis:

  • muitos Unit Tests;
  • uma quantidade menor de Service Tests;
  • poucos UI Tests.

Martin Fowler posteriormente ajudou a popularizar o conceito. O princípio central é simples: uma suíte saudável tende a possuir muito mais testes pequenos e rápidos do que testes amplos executados através de toda a aplicação

alt text

A pirâmide não precisa ser interpretada como uma proporção rígida, e a própria literatura posterior reconhece que sistemas diferentes podem exigir distribuições diferentes. Há estratégias como Testing Trophy e Testing Honeycomb, e as fronteiras entre “unitário” e “integração” nem sempre são consensuais. Fowler observa que a pirâmide continua útil principalmente como uma heurística: utilizar testes de granularidades diferentes e evitar depender excessivamente de testes amplos, lentos e frágeis.

Ou seja, isso continua relevante com IA.

Um agente capaz de alterar código continuamente precisa de feedback rápido. Se pra cada mudança exigir uma suíte E2E de vinte minutos para sabermos se algo fundamental quebrou, o ciclo de desenvolvimento perde boa parte de sua vantagem. Por outro lado, depender apenas de testes unitários também é perigoso. Um agente pode produzir componentes que funcionam perfeitamente isolados e, ainda assim, integrá-los incorretamente.

Por isso, mais importante que seguir literalmente uma pirâmide é construir camadas de confiança:

Camadas de confiança: E2E no topo cobrindo fluxos críticos, Integração no meio verificando componentes trabalhando juntos, Unitário na base cobrindo regras e comportamentos

Cada camada verifica algo diferente: E2E cobre os fluxos críticos, integração verifica os componentes trabalhando juntos, unitário cobre regras e comportamentos.

Na prática, isso significa mapear cada camada pra um tipo específico de risco, não aplicar as três de forma genérica:

  • Unitário cobre as regras de negócio — cada caso de uso testado isoladamente, sem depender de banco, rede ou qualquer colaborador externo. É a camada mais barata de manter e a que aponta o erro mais perto da causa.
  • Integração cobre os pontos onde o sistema encosta no mundo real — implementação de repositório, query no banco, chamada a um serviço externo. O risco aqui raramente é a regra em si, é a forma como ela é persistida, recuperada ou traduzida entre sistemas.
  • E2E cobre o fluxo completo, mas o custo muda conforme a camada: e2e de API (sem navegador, batendo direto no endpoint) ficou barato de escrever e rápido de rodar — hoje dá pra cobrir boa parte das funcionalidades de back-end sem culpa. Já e2e de interface (navegador, clique, tela) continua caro de rodar, mesmo com IA reduzindo o custo de escrever — ali a seletividade ainda vale: só os fluxos que o negócio não pode se dar ao luxo de deixar quebrar sem ninguém perceber.

Quanto mais rápido for o feedback relevante, menor será o intervalo entre gerar uma mudança e descobrir que ela está errada.

Red, Green, Refactor — agora com IA no loop

Outra prática comum quando o assunto é testes automatizados é a prática do TDD (Test-Driven Development, Desenvolvimento Dirigido por Testes, em português)

alt text

O ciclo do TDD popularizado por Kent Beck é simples:

Red: escreva um teste que falha.
Green: implemente apenas o necessário para fazê-lo passar.
Refactor: melhore o design preservando o comportamento.

Atualmente, a própria IA implementa TDD a partir da natureza da própria funcionalidade, dos requisitos funcionais estipulados, respeitando suas regras e comportamentos esperados.

Por exemplo:

Implemente um sistema de cálculo de comissão. Vendas zeradas não geram comissão; vendas de até R$ 10.000 recebem 5%; acima desse valor, aplique a regra da faixa superior. Implemente também testes automatizados para esses comportamentos.

A IA pode então criar a implementação, escrever os testes, executá-los, observar falhas, corrigir o código e executar a suíte novamente. E o princípio permanece: mudanças são produzidas dentro de um ciclo rápido de implementação, verificação e feedback.

Nesse cenário, o papel do desenvolvedor se desloca cada vez mais para definir corretamente o comportamento esperado, cabendo à IA avaliar (e o próprio dev quando viável) se código e testes realmente representam esse comportamento.

Mas nesse contexto em que a IA desenvolve a funcionalidade e os testes, pode surgir um problema: o que acontece quando a própria IA interpreta incorretamente o requisito e escreve tanto o código quanto os testes?

O problema dos testes escritos pela própria IA

Considere este fluxo:

Fluxo: Prompt gera código pela IA, que gera testes pela IA, que passam, e o código vai pra produção, sem nenhuma verificação independente no meio

À primeira vista parece excelente. Mas aí existe uma circularidade: se a IA interpretou incorretamente o requisito, ela pode implementar essa interpretação e depois escrever testes que confirmem exatamente a mesma interpretação, ou seja, código e testes concordam, mas ambos estão errados.

Na prática, poucos times shippam direto de um prompt. O fluxo real costuma ter uma issue, uma feature branch, um PR e um CI rodando antes do merge. Mas isso sozinho não resolve o problema: se a IA escreveu o código e os testes a partir da mesma interpretação errada, o PR vai chegar com CI verde, e se o review for só “testes passaram, diff parece razoável”, a mesma circularidade acontece — só que agora escondida atrás de um processo que parece rigoroso.

Por isso, uma estratégia mais robusta separa, quando importante, especificação de implementação.

Diagrama: Requisitos e Critérios de aceite geram, em paralelo, Testes e Código da IA, que convergem numa etapa de Verificação independente

De toda forma, a pergunta fundamental continua sendo humana — e depende do produto específico e dos critérios de aceite da funcionalidade: quais comportamentos esse produto precisa garantir?

O que devemos testar?

A capacidade de gerar testes em escala cria um risco adicional: confundir quantidade de testes com qualidade da suíte.

Uma IA consegue produzir centenas de testes em minutos. Isso não significa que sejam bons testes.

Uma suíte valiosa precisa detectar mudanças relevantes no comportamento. Testes que só reproduzem detalhes internos da implementação podem aumentar a cobertura e, ao mesmo tempo, tornar refatorações desnecessariamente difíceis — qualquer mudança interna quebra o teste, mesmo quando o comportamento continua correto.

Compare os dois exemplos:

expect(repository.findUser).toHaveBeenCalledTimes(1)

Esse teste verifica um detalhe de implementação: como o sistema chegou no resultado. Troque o repositório por outro, ou adicione um cache na frente da chamada, e o teste quebra (mesmo que o comportamento continue certo).

expect(result.status).toBe('approved')

Esse verifica o comportamento observável: o que o sistema produziu. Sobrevive a praticamente qualquer refatoração interna, contanto que o resultado continue correto.

A pergunta deixa de ser apenas:

Quanto do código está coberto?

E passa a incluir:

Se o comportamento importante mudar incorretamente, algum teste vai falhar?

Essa diferença importa ainda mais agora que gerar código de teste ficou quase gratuito: é fácil pedir pra IA “aumentar a cobertura”, e fácil ela responder com dezenas de testes que travam a implementação no lugar, sem proteger o que de fato importa.

Testes também são contexto para IA

Isso não vale só pra IA, mas sempre serviu também pro próprio desenvolvedor entender a especificação do sistema, bem antes da IA entrar no desenvolvimento.

Um teste bem escrito revela:

Given
    customer has an active subscription

When
    customer cancels the subscription

Then
    access remains active until the billing period ends

Isso contém conhecimento de domínio.

Ao explorar uma base desconhecida, um agente pode analisar testes para descobrir exemplos de utilização, contratos de APIs, invariantes, casos de borda e comportamentos que não devem ser alterados. Nesse sentido, testes passam a desempenhar simultaneamente pelo menos três papéis:

  • verificação, porque detectam comportamentos inesperados;

  • documentação executável, porque registram exemplos do comportamento esperado;

  • contexto para agentes, porque tornam parte das intenções do sistema legível e verificável por ferramentas automatizadas.

Quanto melhor expressarem comportamento, maior seu valor nas três funções.

Testes como infraestrutura de confiança

É de conhecimento de quem é da área que, durante décadas, testes automatizados foram defendidos porque permitem fazer alterações no software com maior segurança, e até mesmo facilidade.

Michael Feathers colocou essa relação entre testes e capacidade de mudança no centro de sua definição de código legado. Mike Cohn mostrou que essa confiança precisa vir de uma estratégia equilibrada de testes. Kent Beck colocou os testes dentro do próprio ciclo de desenvolvimento com TDD. E Dijkstra lembrou, muito antes disso, que testes possuem limites: encontrar evidências de correção não equivale a provar a ausência de defeitos.

Nenhuma dessas ideias perdeu importância com IA. O que mudou foi a velocidade.

Diagrama: antes, o ciclo Ideia → Código → Teste → Revisão → Mudança levava horas ou dias; hoje, Ideia → Gerar → Testar → Feedback → Gerar leva segundos ou minutos

O que mudou não foi o valor dos testes — foi a duração do ciclo entre ter uma ideia e verificar se ela está certa: de horas/dias pra segundos/minutos.

Antes, uma alteração significativa poderia exigir horas ou dias de implementação. Hoje, modelos e agentes conseguem gerar, modificar e refatorar grandes partes de uma base de código em minutos. Quando produzir mudanças se torna mais barato, uma parcela maior do problema se desloca da implementação para especificar, verificar e decidir.

Com isso tudo, é ainda mais indispensável a presença de testes automatizados nessa era atual, e algumas perguntas continuam fundamentais:

Essa mudança fez o que deveria fazer?

O comportamento anterior que deveria permanecer foi preservado?

Os componentes continuam funcionando juntos?

Podemos colocar essa mudança em produção com confiança?

Testes automatizados não respondem perfeitamente a todas essas perguntas. Como Dijkstra observou há décadas, eles não provam a ausência de bugs. Mas fornecem algo especialmente valioso em um processo de desenvolvimento cada vez mais rápido: feedback automatizado, repetível e executável sobre o comportamento do software.

A IA reduz o custo de produzir mudanças. Os testes reduzem o custo de verificar parte dessas mudanças.

É justamente a combinação dessas duas capacidades, geração rápida e verificação rápida, que permite transformar velocidade de desenvolvimento em velocidade de entrega sem transformar, na mesma proporção, velocidade em risco. Na era do desenvolvimento assistido por IA, portanto, testes automatizados não são apenas uma rede de segurança. Eles passam a fazer parte da infraestrutura de confiança sobre a qual humanos e agentes podem modificar software continuamente.

Compartilhar