J'étais dans la même situation que vous, les demi-réponses éparpillées sur Internet étaient assez ennuyeuses, car il semblait que beaucoup de gens avaient le même problème, mais personne ne pouvait être dérangé d'expliquer pleinement comment ils l'ont résolu.
La documentation Sonar fait référence à un projet GitHub avec des exemples utiles. Ce que j'ai fait pour résoudre ce problème, c'était d'appliquer la logique des tests d'intégration aux tests unitaires réguliers (bien que les tests unitaires appropriés devraient être spécifiques au sous-module, ce n'est pas toujours le cas).
Dans le pom.xml parent, ajoutez ces propriétés:
<properties>
<!-- Sonar -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
</properties>
Cela permettra à Sonar de récupérer les rapports de test unitaire pour tous les sous-modules au même endroit (un dossier cible dans le projet parent). Il indique également à Sonar de réutiliser les rapports exécutés manuellement au lieu de lancer les siens. Nous avons juste besoin de faire fonctionner jacoco-maven-plugin pour tous les sous-modules en le plaçant dans le pom parent, à l'intérieur de build / plugins:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.6.0.201210061924</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
destFile
place le fichier de rapport à l'endroit où Sonar le recherchera et le append
fait ajouter au fichier plutôt que de l'écraser. Cela combinera tous les rapports JaCoCo pour tous les sous-modules dans le même fichier.
Sonar examinera ce fichier pour chaque sous-module, car c'est ce que nous lui avons indiqué ci-dessus, nous donnant des résultats de tests unitaires combinés pour les fichiers multi-modules dans Sonar.
mvn package
avant de courirmvn sonar:sonar
pour obtenir le nouveau chemin du rapport généré.FAQ
Des questions du haut de ma tête depuis que je suis devenu fou de jacoco.
Mon serveur d'application (jBoss, Glassfish ..) situé en Irak, en Syrie, peu importe .. Est-il possible d'obtenir une couverture multi-module lors de l'exécution de tests d'intégration? Jenkins et Sonar sont également sur des serveurs différents.
Oui. Vous devez utiliser l' agent jacoco qui s'exécute en mode
output=tcpserver
, jacoco ant lib. Fondamentalement, deuxjar
s. Cela vous donnera 99% de succès.Comment fonctionne l'agent Jacoco?
Vous ajoutez une chaîne
sur votre serveur d'applications JAVA_OPTS et redémarrez-le. Dans cette chaîne, il suffit
[your_path]
de remplacer le chemin vers jacocoagent.jar, stocké (stockez-le!) Sur votre machine virtuelle où le serveur d'applications s'exécute. Depuis que vous démarrez le serveur d'applications, toutes les applications déployées seront surveillées de manière dynamique et leur activité (c'est-à-dire l'utilisation du code) sera prête pour que vous puissiez obtenir le format jacocos .exec par requête tcl.Puis-je réinitialiser l'agent jacoco pour commencer à collecter les données d'exécution uniquement depuis le début de mon test?
Oui, pour cela, vous avez besoin du script jacocoant.jar et ant build situé dans votre espace de travail jenkins.
Donc, fondamentalement, ce dont j'ai besoin de http://www.eclemma.org/jacoco/ est jacocoant.jar situé dans mon espace de travail jenkins et jacocoagent.jar situé sur ma VM de serveur d'applications?
C'est vrai.
Je ne veux pas utiliser fourmi, j'ai entendu dire que le plugin jacoco maven peut faire toutes les choses aussi.
Ce n'est pas vrai, le plugin jacoco maven peut collecter des données de test unitaire et des données de tests d'intégration (voir Arquillian Jacoco ), mais si vous avez par exemple des tests rassurés en tant que build séparé dans jenkins, et que vous souhaitez afficher une couverture multi-module, je peux ne voyez pas comment le plugin maven peut vous aider.
Que produit exactement l'agent jacoco?
Uniquement les données de couverture au
.exec
format. Sonar peut alors le lire.Jacoco a-t-il besoin de savoir où se trouvent mes classes Java?
Non, le sonar le fait, mais pas le jacoco. Lorsque vous faites le
mvn sonar:sonar
chemin vers les classes entre en jeu.Alors qu'en est-il du script de fourmi?
Il doit être présenté dans votre espace de travail jenkins. Mine script de fourmi, j'ai appelé ça
jacoco.xml
ressemble à ça:Deux paramètres obligatoires que vous devez passer lors de l'appel de ce script,
-Dworkspace=$WORKSPACE
utilisez-le pour pointer vers votre espace de travail jenkins et l'-Djacoco.host=yourappserver.com
hôte sanshttp://
Notez également que j'ai placé mon
jacocoant.jar
dans $ {workspace} /tools/jacoco/jacocoant.jarQue devrais-je faire ensuite?
Avez-vous démarré votre serveur d'applications avec jacocoagent.jar?
Avez-vous mis le script ant et jacocoant.jar dans votre espace de travail jenkins?
Si oui, la dernière étape consiste à configurer une version jenkins. Voici la stratégie:
jacocoReset
pour réinitialiser toutes les données précédemment collectées.jacocoReport
pour obtenir le rapportSi tout est correct, vous verrez
it-jacoco.exec
dans votre espace de travail de construction.Regardez la capture d'écran, j'ai également
ant
installé dans mon espace de travail dans$WORKSPACE/tools/ant
dir, mais vous pouvez en utiliser un qui est installé dans votre jenkins.Comment pousser ce rapport dans sonar?
Maven
sonar:sonar
fera le travail (n'oubliez pas de le configurer), pointez-le vers le pom.xml principal pour qu'il s'exécute à travers tous les modules. Utilisez lesonar.jacoco.itReportPath=$WORKSPACE/it-jacoco.exec
paramètre pour indiquer au sondeur où se trouve votre rapport de test d'intégration. Chaque fois qu'il analysera de nouvelles classes de modules, il recherchera des informations sur la couverture dansit-jacoco.exec
.J'ai déjà jacoco.exec dans mon répertoire `target`,` mvn sonar: sonar` l'ignore / le supprime
Par défaut
mvn sonar:sonar
faitclean
et supprime votre répertoire cible, utilisezsonar.dynamicAnalysis=reuseReports
pour l'éviter.la source
NOUVELLE FAÇON DEPUIS LA VERSION 0.7.7
Depuis la version 0.7.7, il existe une nouvelle façon de créer un rapport agrégé:
Vous créez un projet 'rapport' séparé qui rassemble tous les rapports nécessaires (tout objectif du projet d'agrégateur est exécuté avant ses modules, il ne peut donc pas être utilisé).
Le pom racine ressemble à ceci (n'oubliez pas d'ajouter le nouveau module de rapport sous modules):
Les poms de chaque sous-module n'ont pas du tout besoin d'être modifiés. Le pom du module de rapport ressemble à ceci:
Un exemple complet peut être trouvé ici .
la source
Je posterai ma solution car elle est subtilement différente des autres et m'a également pris une journée solide pour bien faire, avec l'aide des réponses existantes.
Pour un projet Maven multi-modules:
Lorsque le
WAR
projet est l'application Web principale,LIB
1 et 2 sont des modules supplémentaires dontWAR
dépend etTEST
où les tests d'intégration se déroulent.TEST
lance une instance Tomcat intégrée (pas via le plugin Tomcat) et exécute leWAR
projet et les teste via un ensemble de tests JUnit. LesWAR
et lesLIB
projets ont tous deux leurs propres tests unitaires.Le résultat de tout cela est que l'intégration et la couverture des tests unitaires sont séparées et peuvent être distinguées dans SonarQube.
ROOT pom.xml
WAR
,LIB
etTEST
pom.xml
héritera de l'exécution des plugins JaCoCo.TEST pom.xml
J'ai également trouvé que l' article de blog de Petri Kainulainens «Création de rapports de couverture de code pour les tests unitaires et d'intégration avec le plugin JaCoCo Maven» était précieux pour le côté configuration de JaCoCo.
la source
agent-for-it
n'est nécessaire que lors de l'exécution des tests dans leTEST
module, mais la configuration actuelle le fait fonctionner pour tous les autres modules, où il n'a aucune valeur. L'amélioration serait d'avoiragent-for-ut
exécuté dans tous les autres modules etagent-for-it
seulement fonctionnerTEST
.Il existe un moyen d'accomplir cela. La magie est de créer un fichier jacoco.exec combiné. Et avec maven 3.3.1, il existe un moyen facile d'obtenir cela. Voici mon profil:
Si vous ajoutez ce profil à votre pom parent et appelez
mvn clean install sonar:sonar -DrunSonar
vous obtenez une couverture complète.La magie ici est
maven.multiModuleProjectDirectory
. Ce dossier est toujours le dossier dans lequel vous avez démarré votre build maven.la source
mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.0.905:sonar -DrunSonar
raison d'uneA required class was missing while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.0.1:sonar: org/sonar/batch/bootstrapper/IssueListener
erreur.La configuration que j'utilise dans mon pom de niveau parent où j'ai des phases de test d'unité et d'intégration séparées.
Je configure les propriétés suivantes dans les propriétés du POM parent
Je place les définitions de plugin sous la gestion des plugins.
Notez que je définis une propriété pour les arguments surefire (surefireArgLine) et failafe (failafeArgLine) pour permettre à jacoco de configurer le javaagent pour qu'il s'exécute avec chaque test.
Sous pluginManagement
Et dans la section construction
Et dans la section reporting
la source
<append>true</append>
config sous lesprepare-agent
sections ...J'ai trouvé une autre solution pour les nouvelles versions de Sonar où le format de rapport binaire de JaCoCo (* .exec) était obsolète et le format préféré est XML (SonarJava 5.12 et supérieur). La solution est très simple et similaire à la solution précédente avec des rapports * .exec dans le répertoire parent de cette rubrique: https://stackoverflow.com/a/15535970/4448263 .
En supposant que la structure de notre projet est:
Vous avez besoin de la configuration suivante du plugin maven build dans le pom du projet global:
Puis construisez un projet avec maven:
Et pour Sonar, vous devez définir la propriété dans l'interface graphique d'administration:
ou en utilisant la ligne de commande:
La description
Cela crée des rapports binaires pour chaque module dans les répertoires par défaut:
target/jacoco.exec
. Crée ensuite des rapports XML pour chaque module dans les répertoires par défaut:target/site/jacoco/jacoco.xml
. Crée ensuite un rapport agrégé pour chaque module dans le répertoire personnalisé${project.basedir}/../target/site/jacoco-aggregate/
relatif au répertoire parent de chaque module. Pour moduleA et moduleB, ce sera le chemin communmoduleC/target/site/jacoco-aggregate/
.Comme moduleB dépend du moduleA, moduleB sera construit en dernier et son rapport sera utilisé comme un rapport de couverture agrégé dans Sonar pour les modules A et B.
En plus du rapport agrégé, nous avons besoin d'un rapport de module normal car les rapports agrégés JaCoCo contiennent des données de couverture uniquement pour les dépendances.
Ensemble, ces deux types de rapports fournissent des données de couverture complète pour Sonar.
Il y a une petite restriction: vous devriez pouvoir écrire un rapport dans le répertoire parent du projet (devrait avoir la permission). Ou vous pouvez définir la propriété
jacoco.skip=true
dans le pom.xml du projet racine (moduleC) etjacoco.skip=false
dans les modules avec des classes et des tests (moduleA et moduleB).la source
En tant que Sonars
sonar.jacoco.reportPath
,sonar.jacoco.itReportPath
etsonar.jacoco.reportPaths
ont tous été obsolètes , vous devriez les utilisersonar.coverage.jacoco.xmlReportPaths
maintenant. Cela a également un impact si vous souhaitez configurer un projet maven multi-modules avec Sonar et Jacoco.Comme @Lonzak l'a souligné , depuis Sonar 0.7.7, vous pouvez utiliser l'objectif d'agrégation des rapports Sonars. Mettez simplement dans votre pom parent la dépendance suivante:
Comme les versions actuelles du plugin jacoco-maven sont compatibles avec les rapports xml, cela créera pour chaque module de son propre dossier cible un dossier site / jacoco-aggregate contenant un
jacoco.xml
fichier.Pour permettre à Sonar de combiner tous les modules, utilisez la commande suivante:
Pour garder ma réponse courte et précise, je n'ai pas mentionné les dépendances
maven-surefire-plugin
etmaven-failsafe-plugin
. Vous pouvez simplement les ajouter sans aucune autre configuration:la source
la source
Vous pouvez appeler une tâche fourmi appelée fusion sur maven, pour regrouper tous les fichiers de couverture (* .exec) dans le même fichier.
Si vous exécutez des tests unitaires, utilisez le package de préparation de phase , si vous exécutez un test d'intégration, utilisez le test de post-intégration .
Ce site a un exemple de comment appeler la tâche de fourmi jacoco dans le projet maven
Vous pouvez utiliser ce fichier fusionné sur le sondeur.
la source
pour avoir des tests unitaires ET des tests d'intégration, vous pouvez utiliser maven-surefire-plugin et maven-failafe-plugin avec des inclusions / exclusions restreintes. Je jouais avec CDI en entrant en contact avec sonar / jacoco, donc je me suis retrouvé dans ce projet:
https://github.com/FibreFoX/cdi-sessionscoped-login/
Peut-être que cela vous aide un peu. dans mon pom.xml, j'utilise "-javaagent" implicite en définissant l'option argLine dans la section de configuration des plugins de test spécifiés. L'utilisation explicite d'ANT dans les projets MAVEN est quelque chose que je ne voudrais pas essayer, pour moi, c'est trop mélanger deux mondes.
Je n'ai qu'un projet maven à module unique, mais peut-être que cela vous aide à adapter le vôtre au travail.
Remarque: peut-être que tous les plugins maven ne sont pas up2date, peut-être que certains problèmes sont résolus dans les versions ultérieures
la source
Cet exemple fonctionne très bien pour moi:
la source