Eu participo do desenvolvimento do projeto Apache Ignite de código-fonte aberto. Enquanto trabalhava no projeto, ficou interessante para mim avaliar a cobertura do teste e foi isso que aconteceu.

A cobertura de testes é a métrica mais popular usada na avaliação da qualidade dos testes de produtos.
Essa é uma das poucas métricas que permite identificar áreas que requerem atenção devido ao risco de perder um erro e também priorizar o trabalho em módulos ou componentes de projeto.
A maneira mais fácil de obter um relatório completo sobre a avaliação da cobertura de teste de um projeto Java é usar o corredor de cobertura incorporado ao IntelliJ IDEA . Ele permite configurar uma coleção de métricas em alguns cliques e executar testes com a geração de relatórios subsequente.
Testando no projeto Apache Ignite
O projeto Apache Ignite usa sua própria estrutura de teste para teste, implementada com base na JUnit 3. No momento da redação, o módulo principal do projeto contém ~ 82 mil testes, a maioria dos quais são componentes e exigem a criação de um cluster de vários nós, incluindo JVMs diferentes. com a preparação concomitante do ambiente.
Vale ressaltar que garantir a operacionalidade de uma base de regressão tão grande não é uma tarefa fácil. A comunidade monitora constantemente o status do produto e corrige os erros encontrados como parte da iniciativa Tornar o Teamcity Green Again .
Os recursos do projeto indicados não permitem executar todos os testes ao mesmo tempo em uma JVM pelos seguintes motivos:
- possível erro OutOfMemoryError;
- possível falha da JVM;
- possíveis impasses;
- incapacidade de iniciar o teste devido a um nó sem interrupção no teste anterior;
- a execução levará três dias em um computador.
Tudo isso impossibilita o uso do IntelliJ IDEA para obter um relatório sobre todos os testes do projeto e requer uma abordagem especial para solucionar o problema.
Preparando e conduzindo a avaliação da cobertura do teste
Com base no trabalho realizado, foi escolhida a abordagem mais confiável para concluir a tarefa, contendo as seguintes etapas:
- Definindo um conjunto de classes de teste;
- Execução para cada classe de teste:
2.1 inicie e execute um conjunto de testes de classe em uma JVM separada com um timer de watchdog que encerrará o encadeamento em caso de congelamentos ou problemas nos testes;
2.2 operações para obter e salvar métricas de cobertura de teste;
2.3 limpar o ambiente após a conclusão dos testes; - Mesclagem de todas as métricas obtidas no parágrafo 2;
- Geração completa de relatórios.
Existem muitas ferramentas para avaliar a cobertura de testes, das quais as mais populares são:
Não vou me debruçar sobre suas diferenças; uma tabela visual comparando os recursos das ferramentas para avaliar a cobertura dos testes é apresentada aqui .
Para resolver o problema, a biblioteca JaCoCo foi escolhida para poder incorporar a solução no TeamCity , na qual a infraestrutura de teste existente do projeto Apache Ignite se baseia. O TeamCity pode funcionar imediatamente com a JaCoCo .
Para automatizar o algoritmo descrito, um script bash e Maven foram usados . A configuração do plug-in Jacoco Maven é implementada por um perfil Maven separado no pom.xml.
O perfil de configuração do plugin JaCoCo é fornecido abaixo e implica uma separação em 2 partidas separadas:
- Execute testes com o agente JaCoCo ( prepare-agent ) conectado para coletar métricas de cobertura de teste. A propriedade 'runDirectory' será transmitida pelo script na inicialização, o que permitirá salvar os resultados das execuções isoladamente;
- Mesclar resultados de execução ( mesclagem ) e geração de relatório ( relatório ).
Configuração do Maven JaCoCo<profile> <id>coverage</id> <properties> <argLine> -ea \ -server \ -Xms1g \ -Xmx6g \ -XX:+HeapDumpOnOutOfMemoryError \ -XX:+AggressiveOpts \ -DIGNITE_UPDATE_NOTIFIER=false \ -DIGNITE_NO_DISCO_ORDER=true \ -DIGNITE_PERFORMANCE_SUGGESTIONS_DISABLED=true \ -DIGNITE_QUIET=false \ -Djava.net.preferIPv4Stack=true \ </argLine> <coverage.dataFile>${runDirectory}/coverage-reports/jacoco-ut.exec</coverage.dataFile> <coverage.outputDir>${runDirectory}/jacoco-ut</coverage.outputDir> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> </configuration> <executions> <execution> <id>default-test</id> <phase>test</phase> <goals> <goal>test</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.1</version> <executions> <execution> <id>default-prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> <configuration> <destFile>${coverage.dataFile}</destFile> </configuration> </execution> <execution> <id>post-merge</id> <phase>validate</phase> <goals> <goal>merge</goal> </goals> <configuration> <fileSets> <fileSet> <directory>${basedir}</directory> <includes> <include>results/*/coverage-reports/jacoco-ut.exec</include> </includes> </fileSet> </fileSets> <destFile>merged.exe</destFile> </configuration> </execution> <execution> <id>generate-report</id> <phase>validate</phase> <goals> <goal>report</goal> </goals> <configuration> <dataFile>${basedir}/merged.exe</dataFile> <outputDirectory>${basedir}/coverage-report</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile>
Abaixo está um script que implementa as etapas descritas anteriormente.
A execução de todos os testes com avaliação de cobertura levou ~ 50 horas em um servidor dedicado: 4 vCPU, 8RAM, 50 SSD, Ubuntu x64 16.04 .
A abordagem descrita pode ser facilmente paralelizada a várias posições, se houver recursos disponíveis, o que reduzirá significativamente o tempo necessário para executar e obter uma avaliação da cobertura do teste. Após incorporar esta solução no TeamCity , o tempo de avaliação da cobertura do teste deve levar cerca de 2 horas.
Resultados
De acordo com os resultados do relatório, a cobertura das instruções do projeto é de ~ 61%.
Cobertura das instruções para os principais componentes:
- Cache - 66%
- Descoberta - 57%
- Computação - 60%
- Stream - 51%
- Binário - 68%
- Transações - 71%
Após analisar os resultados, ficou óbvio que todo o código ativo estava coberto, assim como o código para corrigir problemas típicos. Com esse kit de ferramentas, será possível expandir a cobertura para situações raras e atípicas, tornando o produto ainda mais confiável.
PS Relatório completo para revisão .