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📑
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📑
- Java JDK.
- Stackspot CLI.
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
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.
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
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
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
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
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%)
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
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
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
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.
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>
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
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] ------------------------------------------------------------------------
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:
Os tipos de mutantes que foram gerados com base no grupo escolhido, e alguns detalhes da mutação:
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!😀
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)
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?