Investigating the application of differential fuzzing to support the identification and suppression of equivalent mutants: An experimental study
Este estudo experimental demonstra que o fuzzing diferencial é uma abordagem prática e agnóstica de linguagem para identificar e suprimir eficientemente mutantes equivalentes em diversos projetos de software do mundo real, alcançando pontuações de mutação quase perfeitas ao mesmo tempo em que gera entradas acionáveis para fortalecer suítes de testes tradicionais.
Artigo original sob licença CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). Esta é uma explicação gerada por IA do artigo abaixo. Não foi escrita nem endossada pelos autores. Para precisão técnica, consulte o artigo original. Ler aviso legal completo
O teste de software é o processo de verificar se um programa de computador funciona corretamente, mas encontrar todos os possíveis erros é quase impossível porque os programas são complexos e as entradas são infinitas. Para enfrentar isso, pesquisadores utilizam uma técnica chamada teste de mutação, que funciona introduzindo propositalmente pequenos erros realistas no código para ver se os testes existentes conseguem detectá-los. Se um teste não detecta o erro, significa que o conjunto de testes não é forte o suficiente. No entanto, este método enfrenta um obstáculo persistente: alguns desses erros falsos são tão sutis que não alteram o comportamento do programa de forma alguma, tornando-os impossíveis de detectar. Estes são conhecidos como mutantes equivalentes, e identificá-los geralmente exige que um especialista humano gaste uma quantidade significativa de tempo lendo o código linha por linha, um processo lento e caro que há muito tempo impede o uso generalizado deste método de teste.
Ao mesmo tempo, outro método de teste chamado fuzzing tornou-se uma ferramenta padrão para encontrar falhas de segurança. O fuzzing funciona alimentando um programa com quantidades massivas de dados aleatórios ou malformados para ver se ele trava. Embora seja eficaz na descoberta de bugs que fazem um programa parar de funcionar, o fuzzing tradicional muitas vezes perde o tipo de erro sutil que altera como um programa calcula ou se comporta sem causar um travamento. Um novo estudo realizado por pesquisadores da Universidade de São Paulo explora uma forma de combinar esses dois mundos. Eles investigaram uma técnica chamada fuzzing diferencial, que executa o programa original e uma versão com um pequeno erro lado a lado, alimentando-os com exatamente os mesmos dados e comparando os resultados. Se as duas versões produzirem saídas diferentes, o erro é detectado. Os pesquisadores queriam ver se essa abordagem poderia identificar automaticamente esses mutantes equivalentes esquivos e fazê-lo de forma muito mais rápida do que um humano conseguiria.
Para testar essa ideia, a equipe selecionou seis funções específicas de quatro projetos de software de código aberto bem conhecidos, escritos em quatro linguagens de programação diferentes: C++, C, Go e Python. Esses projetos incluíam o Bitcoin Core, um protocolo de criptomoeda; OpenSSL, uma biblioteca de criptografia; LND, uma rede de canais de pagamento; e Arrow, uma biblioteca de data e hora. Usando uma ferramenta capaz de gerar erros para qualquer linguagem de programação, eles criaram 1.090 variações válidas dessas funções. Antes do início dos testes automatizados, os pesquisadores inspecionaram manualmente os erros para remover aqueles que eram obviamente equivalentes, deixando um conjunto de casos desafiadores para ver se o sistema automatizado conseguiria distinguir o restante. Eles então executaram cinco cenários de teste diferentes sobre esses erros, variando de testes unitários padrão a sessões de fuzzing com limite de tempo, que rodaram por cinco minutos por erro.
Os resultados mostraram que o fuzzing tradicional, que busca apenas por travamentos, foi o método menos eficaz, detectando muito poucos dos erros. Em contraste, a abordagem de fuzzing diferencial provou ser notavelmente poderosa. Quando recebeu um limite de tempo de cinco minutos para testar cada erro, este método identificou e confirmou com sucesso o comportamento dos erros em cinco das seis funções, alcançando uma taxa de sucesso entre 98 e 100 por cento. Para a única função onde inicialmente teve dificuldade, os pesquisadores descobriram que adicionar uma lista simples de palavras-chave esperadas ajudou o sistema a entender melhor a entrada, permitindo eventualmente que atingisse uma pontuação perfeita também. O estudo também revelou que o tempo necessário para encontrar esses erros foi surpreendentemente curto; em média, o sistema encontrou as diferenças em cerca de 30 segundos, muito mais rápido do que os 15 minutos que um humano normalmente leva para analisar um único caso manualmente.
Além de apenas encontrar os erros, os pesquisadores descobriram que os dados usados durante o processo de fuzzing continham um valor oculto. A coleção de entradas que a ferramenta de fuzzing gerou, conhecida como corpus de sementes (seed corpus), continha casos de teste específicos que os testes unitários padrão haviam perdido. Essas entradas foram capazes de eliminar mutantes que os conjuntos de testes tradicionais não conseguiram detectar. Isso sugere que os dados já sendo gerados pelas equipes de segurança podem ser reutilizados para fortalecer os conjuntos de testes regulares, transformando um subproduto do teste de segurança em um recurso para a qualidade geral do software. O estudo também analisou quanto tempo levou para encontrar os erros mais difíceis de detectar, descobrindo que, embora a maioria fosse encontrada rapidamente, alguns exigiram significativamente mais tempo e mostraram um padrão onde a dificuldade variava muito, tal como ocorre quando algumas tarefas levam um pouco mais de tempo enquanto outras levam muito tempo.
Os pesquisadores concluíram que o fuzzing diferencial oferece uma maneira prática e agnóstica a linguagem de apoiar a classificação desses erros difíceis. Ele não requer ferramentas complexas novas ou configurações específicas de linguagem, pois simplesmente compara o código original contra a versão modificada. Ao tratar os erros sobreviventes como candidatos para revisão manual em vez de tentar classificar cada um deles, o método reduz drasticamente a quantidade de esforço humano necessário. O estudo sugere que esta abordagem pode ser integrada aos fluxos de trabalho existentes para filtrar eficientemente os erros que são verdadeiramente equivalentes, deixando os especialistas humanos focarem apenas no pequeno número de casos que permanecem incertos. Esta descoberta indica que uma simples comparação automatizada dos comportamentos do programa pode resolver um problema que há muito tempo é considerado caro e demorado demais para a adoção industrial generalizada.
Afogado em artigos na sua área?
Receba digests diários dos artigos mais recentes que correspondam às suas palavras-chave de pesquisa — com resumos técnicos, no seu idioma.