Garantir a qualidade em sistemas distribuídos, vivos e em constante evolução é um dos compromissos centrais da engenharia no Nubank. Nesse ambiente, onde o Clojure é amplamente adotado e as equipes trabalham com código em mudança contínua, Raíssa Barreira, Desenvolvedora de Software no Nubank, encontrou o ponto de partida para unir prática e pesquisa: entender como a inteligência artificial pode apoiar a geração de testes unitários de forma responsável.

O projeto aborda uma necessidade muito real no desenvolvimento diário e expande as fronteiras de uma área ainda em grande parte inexplorada dentro das linguagens de programação funcional. A pesquisa está sendo conduzida no LABES (Laboratório de Engenharia de Software) no ICMC/USP, sob a orientação do Prof. José Carlos Maldonado e em colaboração com o Prof. Auri Vincenzi, atualmente pesquisador na Universidade do Porto, fortalecendo ainda mais a ponte entre a academia e a indústria.

Onde a pesquisa começa

Raíssa ingressou no Nubank em 2023, e foi aqui que ela teve seu primeiro contato com Clojure. Dessa experiência surgiu a curiosidade de entender como melhorar a qualidade dos testes na linguagem que impulsiona grande parte dos sistemas do Nu.

Nos últimos anos, houve um progresso significativo no uso de modelos de linguagem para gerar testes automaticamente, mas o Clojure raramente aparece nessas investigações. Essa lacuna inspirou a questão que norteia sua pesquisa: como integrar a IA no processo de criação de testes unitários em Clojure de forma ponderada, incremental e que possa ser diretamente comparada ao trabalho escrito por humanos.

Conheça nossas oportunidades

Como funciona a estratégia incremental

A ideia central é construir testes progressivamente. Em vez de criar um único test suite e analisá-lo de uma só vez, o processo evolui em pequenas camadas. Cada camada ajuda a revelar lacunas, refinar testes existentes e preparar o ambiente para avaliações mais rigorosas. Essa abordagem possibilita identificar pontos frágeis antes que se tornem problemas maiores.

No Clojure, essa estratégia se torna especialmente útil, visto que a linguagem favorece a expressividade e a composição, o que aumenta a necessidade de uma verificação cuidadosa em múltiplos caminhos de execução.

A função do teste de cobertura e do teste de mutação

A cobertura de testes mede o quanto do código é efetivamente exercitado pelos testes. Ela ajuda a revelar caminhos esquecidos, branches raras e partes do sistema que nunca são executadas.

Embora não garanta diretamente a qualidade lógica dos testes, ela mostra rapidamente onde estão as lacunas. Na estratégia incremental, essa métrica funciona como um termômetro inicial para guiar o que precisa ser criado ou revisado.

Após atingir um nível sólido de cobertura, a estratégia passa para um estágio mais exigente: o teste de mutação. Ele cria versões levemente alteradas do código original e verifica se os testes conseguem detectar que algo está errado. Quando o problema é identificado, diz-se que o mutante foi “morto” (killed). Quando tudo passa silenciosamente, isso sinaliza fragilidade. Essa técnica fornece uma visão mais profunda sobre o quão capazes os testes realmente são de capturar comportamentos incorretos.

O custo computacional é muito maior, mas o ganho em confiança também é.

Como a inteligência artificial entra nesse processo

Modelos de linguagem são especialmente úteis no início da construção do test suite. Eles entendem instruções textuais, inferem o comportamento das funções e produzem código de teste em Clojure rapidamente. Isso reduz o esforço manual e acelera a criação de uma base inicial de testes.

Ao mesmo tempo, a IA traz desafios que não podem ser ignorados. Os modelos podem “alucinar” comportamentos inexistentes, produzir testes superficiais e dependem muito da clareza da entrada (input). Eles também carecem de mecanismos formais para garantir a correção. Isso significa que os testes gerados precisam ser analisados, revisados e comparados continuamente.

A estratégia incremental surge como uma forma de equilibrar esse cenário. Em vez de depender inteiramente da IA, o processo cria espaço para a validação, a comparação direta com testes escritos por humanos e iterações sucessivas que elevam a qualidade geral do suite.

O pipeline apresentado na pesquisa

O ciclo começa com a criação de duas suítes de teste: uma escrita por desenvolvedores e outra gerada por IA. Ambas são avaliadas através da cobertura. Se a cobertura ficar abaixo do esperado, novos testes são criados e o processo continua até que um nível aceitável seja atingido.

Uma vez que essa etapa amadurece, o ciclo avança para o teste de mutação, onde ambas as suítes são avaliadas e expandidas novamente. Com o tempo, torna-se possível observar como cada suíte evolui e entender onde a IA se aproxima ou diverge da qualidade humana.

O que os primeiros resultados mostram

Nos primeiros cenários, os testes gerados por IA conseguiram superar os testes escritos manualmente, tanto em velocidade quanto na capacidade de eliminar mutantes (killing mutants). A conclusão é promissora, mas ainda limitada, visto que este experimento inicial ainda não representa a complexidade real dos sistemas em produção.

A próxima etapa do estudo envolve a aplicação da estratégia a um conjunto maior e mais diversificado de programas em Clojure. O objetivo é avaliar o volume de testes produzidos, a cobertura alcançada, o número de mutantes eliminados, o esforço computacional envolvido e o consumo de tokens dos modelos de IA. Esses indicadores ajudarão a determinar o custo e o benefício reais da adoção dessa forma de automação em ambientes reais.

A pesquisa de Raíssa reforça a importância de aproximar a academia da indústria. O Nubank opera sistemas de larga escala, distribuídos e de missão crítica. Por isso, qualquer avanço que aumente a qualidade e reduza riscos é significativo.

A estratégia incremental com suporte de IA abre caminhos para evoluir bases de testes legadas, reduzir o esforço em grandes refatorações e fortalecer a confiança dos times em cada alteração implementada em produção.

De forma mais ampla, o estudo enriquece a conversa sobre a adoção responsável da IA no ciclo de vida de desenvolvimento. Não como uma substituição, mas como parte de um sistema que possibilita validação, comparação e melhoria contínua.

A estratégia ainda está em desenvolvimento, mas já mostra potencial. Com mais experimentos, uma base de código mais ampla e ciclos de avaliação adicionais, ela pode se tornar uma ferramenta relevante para a melhoria da qualidade de software em Clojure.

Conheça nossas oportunidades