Participo en el desarrollo del proyecto Apache Ignite de código abierto, mientras trabajaba en el proyecto me resultó interesante evaluar la cobertura de la prueba y esto es lo que surgió.

La cobertura de pruebas es la métrica más popular utilizada para evaluar la calidad de las pruebas de productos.
Esta es una de las pocas métricas que le permite identificar áreas que requieren atención debido al riesgo de perder un error, y también priorizar el trabajo en módulos o componentes del proyecto.
La forma más fácil de obtener un informe completo de evaluación de cobertura de prueba de Java para su proyecto es utilizar el corredor de cobertura integrado en IntelliJ IDEA . Le permite configurar una colección de métricas en un par de clics y ejecutar pruebas con la generación posterior de informes.
Pruebas en el proyecto Apache Ignite
El proyecto Apache Ignite utiliza su propio marco de prueba para las pruebas, implementado sobre la base de JUnit 3. En el momento de la escritura, el módulo del proyecto central contiene ~ 82 mil pruebas, la mayoría de las cuales son componentes y requieren elevar un clúster desde varios nodos, incluidas diferentes JVM. Con la preparación concomitante del medio ambiente.
Vale la pena señalar que garantizar la operatividad de una base de regresión tan grande no es una tarea fácil. La comunidad monitorea constantemente el estado del producto y corrige los errores encontrados como parte de la iniciativa Make Teamcity Green Again .
Las características del proyecto indicadas no permiten ejecutar todas las pruebas a la vez en una JVM por los siguientes motivos:
- posible error OutOfMemoryError;
- posible accidente de la JVM;
- posibles puntos muertos;
- incapacidad para iniciar la prueba debido a un nodo sin detener en la prueba anterior;
- la ejecución durará tres días en una computadora.
Todo esto hace que sea imposible usar IntelliJ IDEA para obtener un informe de todas las pruebas del proyecto y requiere un enfoque especial para resolver el problema.
Preparación y realización de evaluaciones de cobertura de prueba.
En función del trabajo realizado, se eligió el enfoque más confiable para completar la tarea, que contiene los siguientes pasos:
- Definir un conjunto de clases de prueba;
- Ejecución para cada clase de prueba:
2.1. inicie y ejecute un conjunto de pruebas de clase en una JVM separada con un temporizador de vigilancia que terminará el hilo en caso de congelaciones o problemas con las pruebas;
2.2. operaciones para obtener y guardar métricas de cobertura de prueba;
2.3. limpieza del medio ambiente al finalizar las pruebas; - Fusión de todas las métricas obtenidas en el párrafo 2;
- Generación completa de informes.
Existen muchas herramientas para evaluar la cobertura de las pruebas, las más populares son:
No me detendré en sus diferencias; aquí se presenta una tabla visual que compara las capacidades de las herramientas para evaluar la cobertura de las pruebas.
Para resolver el problema, se eligió la biblioteca JaCoCo para poder integrar la solución en TeamCity , en la que se basa la infraestructura de prueba existente del proyecto Apache Ignite . TeamCity puede trabajar fuera de la caja con JaCoCo .
Para automatizar el algoritmo descrito, se utilizó un script bash y Maven . La configuración del complemento Jacoco Maven se implementa mediante un perfil Maven separado en pom.xml.
El perfil de configuración del complemento JaCoCo se proporciona a continuación e implica una separación en 2 inicios separados:
- Ejecute pruebas con el agente JaCoCo (agente de preparación ) conectado para recopilar métricas de cobertura de prueba. El script pasará la propiedad 'runDirectory' al inicio, lo que permitirá guardar los resultados de las ejecuciones de forma aislada;
- Fusionar resultados de ejecución ( fusionar ) y generación de informes ( informe ).
Configuración de 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>
A continuación se muestra un script que implementa los pasos descritos anteriormente.
La ejecución de todas las pruebas con evaluación de cobertura tomó ~ 50 horas en un servidor dedicado: 4 vCPU, 8RAM, 50 SSD, Ubuntu x64 16.04 .
El enfoque descrito se puede paralelizar fácilmente con varios stands, si hay recursos disponibles, lo que reducirá significativamente el tiempo que lleva ejecutar y obtener una evaluación de la cobertura de la prueba. Después de incorporar esta solución en TeamCity , el tiempo de evaluación de la cobertura de la prueba debería tomar aproximadamente 2 horas.
Resultados
Según los resultados del informe, la cobertura de las instrucciones del proyecto es de ~ 61%.
Cobertura de instrucciones para los componentes principales:
- Caché - 66%
- Descubrimiento - 57%
- Calcular - 60%
- Stream - 51%
- Binario - 68%
- Transacciones - 71%
Después de analizar los resultados, se hizo evidente que todo el código activo estaba cubierto, así como el código para solucionar problemas típicos. Con un kit de herramientas de este tipo, será posible ampliar la cobertura a situaciones raras y atípicas, haciendo que el producto sea aún más confiable.
PD Informe completo para revisión .