DEV Community

Marlo Henrique
Marlo Henrique

Posted on • Edited on

Configurando testes de mutação utilizando Stackspot EDP

A Stackspot EDP tem se mostrado um forte aliado no processo de automação de testes, permitindo a criação de novos projetos e a complementação de projetos já existentes.

Neste artigo, vamos explorar como configurar testes de mutação em um projeto backend existente usando um plugin desenvolvido com a Stackspot EDP.

O que são testes de mutação?👥

O Teste de Mutação é uma técnica de teste de software que consiste em alterar partes específicas do código-fonte para verificar se os testes elaborados conseguem identificar os erros resultantes das mudanças.

O objetivo é avaliar a qualidade dos testes e sua capacidade de detectar falhas no código-fonte que foi modificado, por isso as mudanças ou também chamados de mutantes são pequenas para não afetar o objetivo geral do programa.

Essa técnica é também conhecida como estratégia de teste baseada em falhas e é principalmente usada para verificar a qualidade dos testes de unidade que foram desenvolvidos.

Etapas para execução📑

Image description

O processo de Teste de Mutação envolve alguns passos, entre eles:

  • Primeiro, falhas são introduzidas no código-fonte, criando mutantes que devem falhar na execução dos testes.
  • Em seguida, os casos de teste são aplicados tanto ao programa original quanto aos mutantes. Se os resultados dos programas original e mutante forem diferentes, o mutante é eliminado pelo caso de teste, demonstrando sua eficácia.
  • Se os resultados forem os mesmos, o mutante é mantido ativo, e teste mais eficazes precisam ser criados para detectar a mudança entre o programa original e o mutante.

O objetivo final é garantir a qualidade dos casos de teste e a robustez do software a mudanças.

Mudanças em um programa mutante📐

Existem diversas técnicas utilizadas para gerar mutantes, sendo as mais comuns:

  • Operadores de substituição de operando: substituem um operando por outro ou por um valor constante.
  • Operadores de modificação de expressão: alteram a expressão original, inserindo ou substituindo operadores.
  • Operadores de modificação de instrução: alteram a instrução original, inserindo ou removendo instruções.

Essas técnicas podem ser combinadas para gerar mutantes com diferentes tipos de falhas, aumentando a eficácia do Teste de Mutação.

Para obter mais informações sobre as diferentes abordagens de geração de mutantes, você pode consultar a documentação da ferramenta pitest, que está disponível no seguinte link.

Ferramentas🔨

Existem várias ferramentas disponíveis para realizar testes de mutação em projetos Java/Kotlin. Uma das ferramentas mais conhecidas é o Pitest, que será utilizada neste artigo.

Pré-requisito📑

Projeto de exemplo📚

Neste artigo, utilizaremos o projeto pequeno investidor, uma aplicação pessoal que disponibiliza informações do mercado financeiro por meio de uma API que extrai as informações utilizando web scraping.

O projeto foi criado utilizando a linguagem Java e utiliza o gerenciador de dependências Maven. A estrutura do projeto é a seguinte:

├───src │ ├───main │ │ ├───java │ │ │ └───com │ │ │ └───money │ │ │ └───pequenoinvestidor │ │ │ ├───configuration │ │ │ ├───controller │ │ │ ├───model │ │ │ ├───services │ │ │ │ └───imp │ │ │ └───util │ │ └───resources │ └───test │ └───java │ └───com │ └───money │ └───pequenoinvestidor │ └───integração 
Enter fullscreen mode Exit fullscreen mode

Conhecendo nosso plugin🧐

Utilizaremos a stack qa-stacks, quem tem como objetivo, disponibilizar soluções que acelere e simplifique a abordagem de diferentes metodologias de teste.

Os plugins permitem adicionar novas capacidades à sua aplicação. Neste caso, utilizaremos um plugin presente na qa-stacks que realiza as configurações necessárias para a realização de testes de mutação em projetos java.

Image description

Importante: Essa é uma stack para fins didáticos.

Utilizando o plugin🔌

Para utilizar o plugin mutation-java, é necessário estar dentro do diretório da aplicação desejada. Neste exemplo, a aplicação é o pequenoinvestidor.

cd pequenoinvestidor 
Enter fullscreen mode Exit fullscreen mode

Na raiz do projeto, utilizaremos o seguinte comando para aplicar o plugin de configuração de testes de mutação ao projeto:

stk apply plugin qa-tools/mutation-java@0.1.1 
Enter fullscreen mode Exit fullscreen mode

Será necessários fornecer algumas entradas para a configuração do plugin. A primeira delas é referente ao gerenciador de dependências utilizado no projeto. O plugin da suporte a projetos maven e gradle utilizando groovy. Nesse exemplo utilizaremos maven.

? Qual gerenciador de dependenciais do projeto? » 1) Maven 2) Gradle Answer: 1) Maven 
Enter fullscreen mode Exit fullscreen mode

A próxima informação que você precisa fornecer é referente à biblioteca de logs utilizada no projeto. No projeto pequeno investidor, está sendo utilizada a biblioteca org.slf4j.Logger.

? Qual lib de logs utilizada no projeto? (Use shortcuts or arrow keys) 1) java.util.logging 2) org.apache.log4j » 3) org.slf4j 4) org.apache.commons.logging Answer: 3) org.slf4j 
Enter fullscreen mode Exit fullscreen mode

Trechos de logs podem interferir nos resultados do teste de mutação, precisamos informar para a ferramenta pitest ignora trechos de log por meio da configuração avoidCallsTo.

Em seguida, você precisará informar qual é a cobertura de mutantes esperada para o projeto após a execução dos testes de mutação. Como o projeto pequeno investidor possui baixa cobertura de testes unitários, vamos informar o valor de 50%.

 Qual cobertura de mutantes esperada?(1% a 99%) 
Enter fullscreen mode Exit fullscreen mode

A cobertura de mutantes é definida como a porcentagem de mutantes mortos pelo número total de mutantes gerados: (Mutantes Mortos / Número Total de Mutantes) * 100. É um excelente indicador para avaliar se os testes unitários estão conseguindo identificar os mutantes. Taxas elevadas de mutantes sobreviventes resultam em baixa cobertura de mutantes.

A seguir você precisara informar qual o grupo de mutantes será configurado no seu projeto. Essa é uma informação referente a quantidade de variações/tipos de mutantes que serão gerados. Por padrão a ferramenta pitest considera os mutantes OLD_DEFAULTS, no entanto vamos selecionar a opção DEFAULTS:

? Grupo de mutantes a ser utilizado? 1) OLD_DEFAULTS » 2) DEFAULTS 3) STRONGER 4) ALL Answer: 2) DEFAULTS 
Enter fullscreen mode Exit fullscreen mode

Mais detalhes sobre as mutações geradas no código da aplicação com base no grupo escolhido podem ser conferidas em mutators .

Chegamos a duas informações extremamente importantes. Primeiramente, precisamos informar ao Pitest o pacote onde se localizam as classes de negocio da nossa aplicação, para que a ferramenta possa gerar os mutantes. Embora pudessemos simplesmente informar com.* para que a ferramenta gere mutantes para todas as classes do projeto, isso não é uma prática recomendada. Neste exemplo, informarei o seguinte pacote com.money.pequenoinvestidor.services.imp.CalculoServiceImp

? Qual o pacote das classes a serem gerados mutantes?com.money.pequenoinvestidor.services.imp.CalculoServiceImp 
Enter fullscreen mode Exit fullscreen mode

Nos testes de mutação, é importante estar atento as classes em que as mutações no código serão aplicadas. O objetivo é avaliar se mudanças nas regras de negócio são identificadas pelos testes unitários. Dependendo da arquitetura do projeto, é recomendado concentrarmos nas classes que implementam essas regras de negócio, ignorando interfaces, classes abstratas ou outros pontos do código que podem interferir no resultado dos testes de mutação.

precisamos informar o pacote onde estão localizadas as classes de testes do nosso projeto. Neste exemplo, utilizaremos o pacote de testes com.money.pequenoinvestidor.TestCalculoServiceImp

? Qual o pacote dos testes unitários? com.money.pequenoinvestidor.TestCalculoServiceImp 
Enter fullscreen mode Exit fullscreen mode

Ao final do processo, a Stackspot informará que o plugin foi aplicado com sucesso ao projeto:

- Plugin qa-tools/mutation-java@0.1.1 aplicado. 
Enter fullscreen mode Exit fullscreen mode

Acessando o arquivo pom.xml do projeto pequeno investido, podemos observar que as configurações para o plugin do pitest foram aplicadas, e as entradas que fornecemos serviram como base para a configuração dos testes de mutação:

<plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M7</version> <configuration> <excludes> <exclude>**/FiisTest.java</exclude> </excludes> </configuration> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.4.0</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.pitest</groupId> <artifactId>pitest-maven</artifactId> <version>1.5.0</version> <configuration> <targetClasses> <param>com.money.pequenoinvestidor.services.imp.CalculoServiceImp</param> </targetClasses> <targetTests> <param>com.money.pequenoinvestidor.TestCalculoServiceImp</param> </targetTests> <mutators> <mutator>DEFAULTS</mutator> </mutators> <outputFormats> <outputFormat>HTML</outputFormat> <outputFormat>XML</outputFormat> </outputFormats> <failWhenNoMutations>false</failWhenNoMutations> <avoidCallsTo> <avoidCallsTo>org.slf4j</avoidCallsTo> </avoidCallsTo> <mutationThreshold>50</mutationThreshold> </configuration> </plugin> </plugins> 
Enter fullscreen mode Exit fullscreen mode

Executando os teste de mutação😁

Uma vez que a ferramenta Pitest foi configurada em nosso projeto, podemos executar os testes de mutação com facilidade. Para isso, basta utilizar o seguinte comando com o Maven:

mvn test-compile org.pitest:pitest-maven:mutationCoverage 
Enter fullscreen mode Exit fullscreen mode

Teremos uma saída semelhante a esta:

-------------------------------------------------------------------------------- > Total : 1 seconds -------------------------------------------------------------------------------- ================================================================================ - Statistics ================================================================================ >> Generated 14 mutations Killed 11 (79%) >> Ran 19 tests (1.36 tests per mutation) [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.977 s [INFO] Finished at: 2024-07-12T18:28:29-03:00 [INFO] ------------------------------------------------------------------------ 
Enter fullscreen mode Exit fullscreen mode

Podemos observar que apensar de um limite de cobertura de 50% definido, os resultados para a classe CalculoServiceImp foram interessantes, de 14 mutações geradas no código 79% foram identificadas por testes unitários existentes.

O pitest já gera relatórios de saída, e por meio deles podemos identificar alguns pontos como dados de cobertura:

Image description

Os tipos de mutantes que foram gerados com base no grupo escolhido, e alguns detalhes da mutação:

Image description

Conclusão💖

Muito além de escrever testes unitários, precisamos nos preocupar com a qualidade dos testes que são escritos. É aí que entra o teste de mutação, uma técnica poderosa que pode nos ajudar a identificar falhas na lógica do código.

Aqui podemos observar mais um exemplo pratico em que a Stackspot EDP pode ser utilizada para nos auxiliar na parte de testes e qualidade de software. Ressaltando mais um vez o quão simples você pode tornar a configuração de testes de mutação utilizando a ferramenta.✨

Sinta-se à vontade para qualquer dúvida!😀

📩 linkedin
🐱‍👤 github

Quer sabe mais sobre stackspot EDP? vou esta deixando o link para o github oficial onde você pode encontrar os principais contatos para o time da stackspot.✨

Top comments (1)

Collapse
 
rafaelleitao profile image
Rafael L. Oliveira

Excelente post.. muito legal o material com stackspot voltado para qualidade..
Seria possivel usar o K6 com o stackspot para facilitar a configuração do projeto?