- A ferramenta chamada TestGen-LLM foi apresentada no artigo publicado pela Meta em fevereiro, "Automated Unit Test Improvement using Large Language Models at Meta"
- O objetivo dessa ferramenta é aumentar a cobertura de testes de forma totalmente automatizada, garantindo melhorias em relação à base de código existente
- Como a Meta não divulgou o código do TestGen-LLM, decidiu-se implementá-lo diretamente como parte do Cover Agent open source
- Aqui são compartilhados o processo de implementação, as descobertas e os problemas encontrados ao usar o TestGen-LLM em bases de código reais
Critérios para geração automática de testes
- A geração automática de testes com IA generativa não é algo novo
- A maioria dos LLMs é boa em gerar código e também consegue gerar testes
- O problema mais comum que desenvolvedores enfrentam ao gerar testes com LLMs é que a maior parte dos testes gerados não funciona ou não agrega valor
- Para superar isso, os autores do TestGen-LLM propõem os seguintes critérios para testes unitários de regressão:
- O teste compila e executa corretamente?
- O teste aumenta a cobertura de código?
- Se essas duas perguntas básicas não puderem ser respondidas, não há motivo para aceitar ou analisar testes gerados por LLM
- Se essas perguntas forem superadas, então vem a revisão manual seguinte
- Quão bem o teste foi escrito?
- Quanto valor ele realmente pode agregar?
- Ele atende a requisitos adicionais?
Abordagem do TestGen-LLM e resultados reportados
- O TestGen-LLM (e o Cover-Agent) roda de forma totalmente headless
- Primeiro, ele gera muitos testes; depois, filtra os que não compilam ou não executam, descarta os que não passam e elimina os que não aumentam a cobertura de código
- Em casos muito controlados, a proporção entre testes gerados e testes que passam por todas as etapas é de 1:4, e em cenários reais os autores da Meta relatam uma proporção de 1:20
- Após o processo automatizado, a Meta faz com que revisores humanos aceitem ou rejeitem os testes
- Os autores do artigo afirmam que, no melhor caso, observaram uma taxa de aceitação média de 1:2, com 73% de aceitação
- Como descrito no artigo, a ferramenta TestGen-LLM gera, a cada execução, um único teste que é adicionado ao conjunto de testes existente previamente escrito por desenvolvedores especialistas
- Além disso, ela não necessariamente gera um teste para um determinado conjunto de testes
Implementação do Cover-Agent
- O Cover-Agent v0.1 foi implementado da seguinte forma:
- Receber entrada do usuário (arquivo-fonte alvo dos testes, conjunto de testes existente a ser melhorado, relatório de cobertura, comandos para build e execução do conjunto de testes, meta de cobertura de código e número máximo de iterações, além de contexto adicional e opções de prompt)
- Gerar mais testes no mesmo estilo
- Validar esses testes usando o ambiente de runtime (se compilam e passam)
- Revisar métricas, como aumento de cobertura de código, para verificar se os testes agregam valor
- Atualizar o conjunto de testes existente e o relatório de cobertura
- Repetir até que o código atinja os critérios (alcançar o limite de cobertura de código ou o número máximo de iterações)
Problemas enfrentados ao implementar e revisar o TestGen-LLM
- Nos exemplos apresentados no artigo, foi usado Kotlin para escrever testes, uma linguagem em que espaços em branco não são importantes
- Já em linguagens como Python, tabs e espaços não só importam como são essenciais para o parser
- Modelos menos sofisticados, como o GPT 3.5, não retornam de forma consistente código com a indentação correta, mesmo com prompts explícitos
- Um exemplo de problema causado por isso são classes de teste escritas em Python, em que cada função de teste precisa estar devidamente indentada
- Isso precisou ser considerado ao longo de todo o ciclo de vida de desenvolvimento, adicionando mais complexidade em torno da biblioteca de pré-processamento
- Ainda há muitos pontos a melhorar para tornar o Cover-Agent robusto nesses cenários
- Como parte do fluxo do Cover-Agent, foi adicionada uma funcionalidade que permite ao usuário fornecer entradas ou instruções extras ao LLM (opção
--additional-instructions)
- Com isso, desenvolvedores podem personalizar o Cover-Agent fornecendo informações adicionais específicas do projeto
- Por exemplo, essas instruções podem ser usadas para orientar o Cover-Agent a criar um conjunto de testes rico, com edge cases significativos
- Em linha com a tendência geral de maior adoção de Retrieval-Augmented Generation (RAG) em aplicações baseadas em IA, confirmou-se que mais contexto junto com a geração de testes unitários permite testes de maior qualidade e taxas de aprovação mais altas
- Para usuários que desejam adicionar manualmente bibliotecas extras ou documentos de design em texto como contexto para o LLM, foi oferecida a opção
--included-files para melhorar o processo de geração de testes
- Códigos complexos que exigem várias iterações também apresentam outro desafio para o LLM
- À medida que testes falhos (ou que não agregavam valor) eram gerados, começou-se a notar um padrão em que os mesmos testes não aceitos eram sugeridos repetidamente nas iterações seguintes
- Para resolver isso, foi adicionada ao prompt uma seção de "testes que falharam", para passar esse feedback ao LLM e evitar que ele repita testes que já foram considerados inutilizáveis (ou seja, quebrados ou com ganho insuficiente de cobertura)
- Outro problema levantado ao longo de todo esse processo é que não é possível adicionar imports de bibliotecas ao expandir o conjunto de testes existente
- Desenvolvedores às vezes podem ser míopes e usar apenas uma abordagem única de framework de testes no processo de geração
- Além de muitos frameworks de mocking diferentes, outras bibliotecas também podem ajudar a alcançar cobertura de testes
- Como o artigo do TestGen-LLM (e o Cover-Agent) tem como objetivo expandir o conjunto de testes existente, reconstruir completamente toda a classe de testes está fora do escopo
- Esse é um limite da expansão de testes em contraste com a geração de testes, e há planos para lidar com isso em futuras iterações
- É importante distinguir que, na abordagem do TestGen-LLM, cada teste requer revisão manual do desenvolvedor antes que o próximo teste seja proposto
- Já no Cover-Agent, são gerados, validados e propostos o máximo possível de testes sem intervenção manual ao longo do processo, até atingir os requisitos de cobertura (ou parar no limite máximo de iterações)
- Isso cria uma abordagem não intrusiva para geração automática de testes, rodando em segundo plano com IA para que o desenvolvedor possa revisar todo o conjunto de testes de uma vez quando o processo terminar
Conclusão e planos futuros
- Muitas pessoas (inclusive eu) estão empolgadas com o artigo e a ferramenta TestGen-LLM, mas este post falou sobre suas limitações
- Ainda estamos, na minha visão, na era do assistente de IA, e não de um colega de equipe de IA capaz de executar workflows totalmente automatizados
- Ao mesmo tempo, um fluxo bem projetado pode ajudar desenvolvedores a gerar automaticamente candidatos a testes e aumentar a cobertura de código em muito menos tempo, e isso é algo que se pretende desenvolver e compartilhar no Cover-Agent
- Pretende-se continuar desenvolvendo métodos de ponta relacionados ao domínio de geração de testes e integrá-los ao repositório open source do Cover-Agent
- Espera-se que todos os interessados em IA generativa para testing colaborem e ajudem a expandir as capacidades do Cover Agent, além de inspirar pesquisadores a explorar novas técnicas de geração de testes usando essa ferramenta open source
- Um roadmap de desenvolvimento foi adicionado ao repositório open source do Cover-Agent no GitHub, e a expectativa é ver contribuições ao repositório com base nesse roadmap ou em ideias próprias
- A visão do Cover-Agent é rodar automaticamente no futuro para todas as solicitações pre/post-pull request, sugerindo automaticamente melhorias em testes de regressão que funcionem e sejam validadas por aumentar a cobertura de código
- Imagina-se o Cover-Agent analisando automaticamente a base de código e abrindo PRs com conjuntos de testes
- Vamos usar IA para lidar com mais eficiência com as tarefas de que não gostamos!
Ainda não há comentários.