Как да конфигурирам мулти-модулен Maven + Sonar + JaCoCo, за да предоставя обединен отчет за покритие?

Търсих нагоре и надолу в интернет за този. Има много полуотговори, свързани със свойства на Maven като ${sonar.jacoco.reportPath} или org.jacoco:jacoco-maven-plugin:prepare-agent или настройка maven-surefire-plugin argLine с -javaagent.

По някакъв начин нито един от тези отговори, самостоятелно или в комбинация, не произвежда това, което преследвам: отчет за покритие, който показва клас като покрит, ако се използва в тестове по-високо в стека, като например използвани обекти от DAO, въпреки че не беше напълно покрит от тестове в собствения си модул.

Има ли някъде окончателна конфигурация, за да се постигне това, моля?


person Stewart    schedule 23.10.2012    source източник


Отговори (12)


Бях в същата ситуация като вас, половинчатите отговори, разпръснати из интернет, бяха доста досадни, тъй като изглеждаше, че много хора имат същия проблем, но никой не можеше да си направи труда да обясни напълно как са го решили.

Документите на Sonar се отнасят до проект на GitHub с примери, които са полезни. Това, което направих, за да разреша това, беше да приложа логиката на интеграционните тестове към обикновените модулни тестове (въпреки че правилните модулни тестове трябва да са специфични за подмодула, това не винаги е така).

В родителския pom.xml добавете тези свойства:

<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>

Това ще накара Sonar да вземе отчети за тестване на модули за всички подмодули на едно и също място (целева папка в родителския проект). Той също така казва на Sonar да използва повторно изготвените ръчно отчети, вместо да пуска свои собствени. Просто трябва да накараме jacoco-maven-plugin да работи за всички подмодули, като поставим това в родителския pom, вътре в 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 поставя отчетния файл на мястото, където Sonar ще го търси и append го кара да се добавя към файла, вместо да го презаписва. Това ще комбинира всички JaCoCo отчети за всички подмодули в един и същи файл.

Sonar ще разгледа този файл за всеки подмодул, тъй като това е, към което го посочихме по-горе, което ни дава комбинирани резултати от тестване на модули за многомодулни файлове в Sonar.

person mpontes    schedule 20.03.2013
comment

Просто направете това, което бихте направили при липса на директива, т.е.:

class DirectiveController{
   static $inject = ['$scope']; // fixed a few typos here
   constructor ($scope){
       $scope.vm = this;        // this is the pattern I recommend for all controllers
       this.myProperty = 'default';
   }

   public myProperty:string;
}

За да научите повече за този модел, вижте: http://www.youtube.com/watch?v=WdtVn_8K17E&hd=1

- person Stewart; 03.04.2013
comment
Работи! Трябваше да направя нов mvn package преди да изпълня mvn sonar:sonar, за да генерирам новия път на отчета. - person thomasa88; 14.10.2014
comment
допълнително наблюдение за многомодулен проект, Многомодулен проект се дефинира от родителски POM, препращащ към един или повече подмодули. Моята настройка за изграждане на реактор беше малко по-различна. Проектите на подмодула имаха различен „родителски“ pom, а не родителският проект с pom опаковка. В такъв случай трябваше да дефинирам плъгина jacoco в отделни подмодули. Също така свойството ‹sonar.jacoco.reportPath› трябва да бъде заменено, за да се постигне желаното агрегиране на отчетите на jacoco. Дневникът на Maven е доста удобен. Следете фазата „jacoco-maven-plugin:xxx:prepare-agent“ и регистрационния файл „Sensor JaCoCoSensor“. - person Rishi; 21.10.2015
comment
обобщавайки по-ранния ми коментар - понякога трябва да добавите jacoco-maven-plugin към отделни pom файлове на подмодули. Също така свойството ‹sonar.jacoco.reportPath› се нуждае от настройка според pom йерархията на подмодулите. - person Rishi; 21.10.2015
comment
Също така имах много трудности при намирането на агрегиране на покритие на многомодулен тест. Този отговор просто ми помогна.. - person Kavindu Dodanduwa; 29.02.2016
comment
Според примера, свойството sonar.jacoco.itReportPath трябва да се използва за получаване на обединени резултати в цялостното покритие на кода. Моля, актуализирайте отговора. - person Yves Martin; 21.04.2016
comment
sonar.dynamicAnalysis също е отхвърлен: docs.sonarqube.org/display/SONAR /Версия+4.3+Надстройка+Бележки - person Yves Martin; 21.04.2016
comment
Актуализирана връзка: docs.sonarqube.org/display/SONARQUBE53/ - person Lonzak; 13.01.2017
comment
Имах същия проблем и го реших по същия начин. хубаво е да видя някой да го документира - person phury; 19.03.2018
comment
Това ще покаже ли покритието на зависимите модули поради модулен тест в модул? - person JITHIN_PATHROSE; 08.10.2018

ЧЗВ

Въпроси от върха на главата ми, откакто полудях по жакоко.

Моят сървър за приложения (jBoss, Glassfish..), намиращ се в Ирак, Сирия, каквото и да е.. Възможно ли е да се получи многомодулно покритие, когато се изпълняват интеграционни тестове на него? Дженкинс и Сонар също са на различни сървъри.

да Трябва да използвате jacoco агент, който работи в режим output=tcpserver, jacoco ant lib . По принцип две jar. Това ще ви осигури 99% успех.

Как действа агентът жакоко?

Добавяте низ

-javaagent:[your_path]/jacocoagent.jar=destfile=/jacoco.exec,output=tcpserver,address=*

към вашия сървър за приложения JAVA_OPTS и го рестартирайте. В този низ само [your_path] трябва да се замени с пътя към jacocoagent.jar, съхранен (съхранявайте го!) на вашата виртуална машина, където работи сървърът на приложения. От момента, в който стартирате сървъра за приложения, всички приложения, които се внедряват, ще бъдат динамично наблюдавани и тяхната активност (което означава използване на код) ще бъде готова за получаване във формат jacocos .exec чрез tcl заявка.

Мога ли да нулирам агента на jacoco, за да започне да събира данни за изпълнение само от момента, в който тестът ми започне?

Да, за тази цел имате нужда от jacocoant.jar и скрипт за изграждане на мравка, намиращ се във вашето работно пространство на jenkins.

Така че основно това, от което се нуждая от http://www.eclemma.org/jacoco/ е jacocoant.jar, намиращ се в работното ми пространство на jenkins, и jacocoagent.jar, намиращ се на моя сървър за приложения VM?

Това е вярно.

Не искам да използвам ant, чувал съм, че плъгинът jacoco maven също може да прави всички неща.

Това не е правилно, плъгинът jacoco maven може да събира данни от модулни тестове и някои данни от интеграционни тестове (вижте Arquillian Jacoco), но ако имате например сигурни тестове като отделна компилация в jenkins и искате да покажете многомодулно покритие, не виждам как плъгинът maven може да ви помогне.

Какво точно произвежда жакоко агентът?

Само данни за покритие във формат .exec. След това сонарът може да го разчете.

Трябва ли jacoco да знае къде се намират моите java класове?

Не, сонарът го прави, но не и жакоко. Когато направите mvn sonar:sonar пътят към класовете влиза в действие.

И така, какво ще кажете за скрипта на мравката?

Трябва да бъде представен във вашето работно пространство на jenkins. Моят ant скрипт, нарекох го jacoco.xml, изглежда така:

<project name="Jacoco library to collect code coverage remotely" xmlns:jacoco="antlib:org.jacoco.ant">
    <property name="jacoco.port" value="6300"/>
    <property name="jacocoReportFile" location="${workspace}/it-jacoco.exec"/>

    <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
        <classpath path="${workspace}/tools/jacoco/jacocoant.jar"/>
    </taskdef>

    <target name="jacocoReport">
            <jacoco:dump address="${jacoco.host}" port="${jacoco.port}" dump="true" reset="true" destfile="${jacocoReportFile}" append="false"/>
    </target>

    <target name="jacocoReset">
            <jacoco:dump address="${jacoco.host}" port="${jacoco.port}" reset="true" destfile="${jacocoReportFile}" append="false"/>
        <delete file="${jacocoReportFile}"/>
    </target>
</project>

Два задължителни параметъра, които трябва да подадете, когато извиквате този скрипт -Dworkspace=$WORKSPACE го използвайте, за да посочите вашето работно пространство на jenkins и -Djacoco.host=yourappserver.com хост без http://

Забележете също, че поставих моя jacocoant.jar в ${workspace}/tools/jacoco/jacocoant.jar

Какво трябва да направя след това?

Стартирахте ли своя сървър за приложения с jacocoagent.jar?

Поставихте ли ant script и jacocoant.jar във вашето работно пространство на jenkins?

Ако да, последната стъпка е да конфигурирате компилация на jenkins. Ето я стратегията:

  1. Извикайте ant target jacocoReset, за да нулирате всички събрани преди това данни.
  2. Пуснете вашите тестове
  3. Извикайте ant target jacocoReport, за да получите отчет

Ако всичко е наред, ще видите it-jacoco.exec във вашето работно пространство за изграждане.

Погледнете екранната снимка, аз също имам ant инсталиран в моето работно пространство в $WORKSPACE/tools/ant dir, но можете да използвате такъв, който е инсталиран във вашия jenkins.

въведете описание на изображението тук

Как да прокарам този отчет в сонара?

Maven sonar:sonar ще свърши работата (не забравяйте да го конфигурирате), насочете го към main pom.xml, така че да премине през всички модули. Използвайте параметър sonar.jacoco.itReportPath=$WORKSPACE/it-jacoco.exec, за да кажете на сонара къде се намира вашият доклад от теста за интеграция. Всеки път, когато ще анализира нови модулни класове, ще търси информация за покритието в it-jacoco.exec.

Вече имам jacoco.exec в моята директория `target`, `mvn sonar:sonar` го игнорира/премахва

По подразбиране mvn sonar:sonar прави clean и изтрива вашата целева директория, използвайте sonar.dynamicAnalysis=reuseReports, за да го избегнете.

person ZuzEL    schedule 23.05.2014

НОВ НАЧИН ОТ ВЕРСИЯ 0.7.7

От версия 0.7.7 има нов начин за създаване на обобщен отчет:

Създавате отделен проект за „отчет“, който събира всички необходими отчети (Всяка цел в проекта на агрегатора се изпълнява преди неговите модули, следователно не може да се използва).

aggregator pom
  |- parent pom
  |- module a
  |- module b
  |- report module 

Root pom изглежда така (не забравяйте да добавите новия модул за отчет под модули):

<build>
<plugins>
  <plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.8</version>
    <executions>
      <execution>
        <id>prepare-agent</id>
        <goals>
          <goal>prepare-agent</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>

The poms from each sub module doesn't need to be changed at all. The pom from the report module looks like this:

<!-- Add all sub modules as dependencies here -->
<dependencies>
  <dependency>
    <module a>
  </dependency>
  <dependency>
    <module b>
  </dependency>
 ...

  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.7.8</version>
        <executions>
          <execution>
            <id>report-aggregate</id>
            <phase>verify</phase>
            <goals>
              <goal>report-aggregate</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

A full exmple can be found here.

person Lonzak    schedule 13.01.2017
comment
Това работи. Общият отчет показва кумулативното покритие на кода за всички модули. Опитвали ли сте някога да видите този кумулативен отчет в Sonar? Използвах sonar-qube, за да прочета jacoco.exec за отделни отчети, но с този обобщен отчет не виждам обобщен jacoco.exec в модула за отчети. - person Swetha V; 07.02.2017
comment
@SwethaV Има ли успех в това? Ние сме в същата позиция и трябва да намерим начин да генерираме агрегирания exec :) - person Vinky; 08.11.2017
comment
Използваме sonar qube версия 6.X, която има собствена страница за тестово покритие, така че нямам нужда от jacoco там. За по-стара версия инсталирахме приставката cobertura, която също предостави тази функционалност... - person Lonzak; 09.11.2017

Ще публикувам моето решение, тъй като то е леко различно от другите и също така ми отне солиден ден, за да се оправя, с помощта на съществуващите отговори.

За многомодулен проект на Maven:

ROOT
|--WAR
|--LIB-1
|--LIB-2
|--TEST

Когато проектът WAR е основното уеб приложение, LIB 1 и 2 са допълнителни модули, от които зависи WAR, а TEST е мястото, където живеят тестовете за интеграция. TEST завърта вграден екземпляр на Tomcat (не чрез плъгин Tomcat) и изпълнява WAR проект и ги тества чрез набор от JUnit тестове. И двата проекта WAR и LIB имат свои собствени модулни тестове.

Резултатът от всичко това е интеграцията и тестовото покритие на модула, които са разделени и могат да бъдат разграничени в SonarQube.

ROOT pom.xml

<!-- Sonar properties-->
<sonar.jacoco.itReportPath>${project.basedir}/../target/jacoco-it.exec</sonar.jacoco.itReportPath>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>

<!-- build/plugins (not build/pluginManagement/plugins!) -->
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.6.201602180812</version>
    <executions>
        <execution>
            <id>agent-for-ut</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
            <configuration>
                <append>true</append>
                <destFile>${sonar.jacoco.reportPath}</destFile>
            </configuration>
        </execution>
        <execution>
            <id>agent-for-it</id>
            <goals>
                <goal>prepare-agent-integration</goal>
            </goals>
            <configuration>
                <append>true</append>
                <destFile>${sonar.jacoco.itReportPath}</destFile>
            </configuration>
        </execution>
    </executions>
</plugin>

WAR, LIB и TEST pom.xml ще наследят изпълнението на добавките JaCoCo.

TEST pom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.19.1</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
            <configuration>
                <skipTests>${skip.tests}</skipTests>
                <argLine>${argLine} -Duser.timezone=UTC -Xms256m -Xmx256m</argLine>
                <includes>
                    <includes>**/*Test*</includes>
                </includes>
            </configuration>
        </execution>
    </executions>
</plugin>

Намерих също Публикация в блога на Petri Kainulainens „Създаване на отчети за покритие на кода за модулни и интеграционни тестове с плъгина JaCoCo Maven“, за да бъде ценна за настройката на JaCoCo.

person markdsievers    schedule 17.06.2016
comment
Трябва да актуализирам тази публикация на някакъв етап, тъй като всъщност е малко неоптимална. agent-for-it е необходим само при изпълнение на тестовете в TEST модул, но текущата конфигурация го кара да се изпълнява за всеки друг модул, където няма стойност. Подобрението би било agent-for-ut да работи във всички други модули, а agent-for-it да работи само в TEST. - person markdsievers; 13.05.2017

Намерих друго решение за нови версии на Sonar, където двоичният формат на отчета на JaCoCo (*.exec) е остарял и предпочитаният формат е XML (SonarJava 5.12 и по-нова версия). Решението е много просто и подобно на предишното решение с *.exec отчети в родителската директория от тази тема: https://stackoverflow.com/a/15535970/4448263.

Ако приемем, че структурата на нашия проект е:

moduleC - aggregate project's pom
  |- moduleA - some classes without tests
  |- moduleB - some classes depending from moduleA and tests for classes in both modules: moduleA and moduleB

Имате нужда от следната конфигурация на плъгин за изграждане на maven в pom на сборния проект:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.5</version>
    <executions>
        <execution>
            <id>prepare-and-report</id>
            <goals>
                <goal>prepare-agent</goal>
                <goal>report</goal>
            </goals>
        </execution>
        <execution>
            <id>report-aggregate</id>
            <phase>verify</phase>
            <goals>
                <goal>report-aggregate</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.basedir}/../target/site/jacoco-aggregate</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

След това изградете проект с maven:

mvn clean verify

А за Sonar трябва да зададете свойство в GUI за администриране:

sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml,../target/site/jacoco-aggregate/jacoco.xml

или чрез командния ред:

mvn sonar:sonar -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml,../target/site/jacoco-aggregate/jacoco.xml

Описание

Това създава двоични отчети за всеки модул в директории по подразбиране: target/jacoco.exec. След това създава XML отчети за всеки модул в директории по подразбиране: target/site/jacoco/jacoco.xml. След това създава обобщен отчет за всеки модул в персонализирана директория ${project.basedir}/../target/site/jacoco-aggregate/, която е относителна към родителската директория за всеки модул. За moduleA и moduleB това ще бъде общ път moduleC/target/site/jacoco-aggregate/.

Тъй като moduleB зависи от moduleA, moduleB ще бъде изграден последен и неговият отчет ще се използва като отчет за обобщено покритие в Sonar и за двата модула A и B.

В допълнение към сборния отчет се нуждаем от нормален модулен отчет, тъй като сборните отчети на JaCoCo съдържат данни за покритие само за зависимости.

Заедно тези два типа отчети предоставят данни за пълно покритие за Sonar.

Има едно малко ограничение: трябва да можете да пишете отчет в родителската директория на проекта (трябва да имате разрешение). Или можете да зададете свойството jacoco.skip=true в pom.xml на основния проект (moduleC) и jacoco.skip=false в модули с класове и тестове (moduleA и moduleB).

person keddok    schedule 11.03.2020

Има начин да постигнете това. Магията е да създадете комбиниран файл jacoco.exec. И с maven 3.3.1 има лесен начин да получите това. Ето моя профил:

<profile>
    <id>runSonar</id>
    <activation>
        <property>
            <name>runSonar</name>
            <value>true</value>
        </property>
    </activation>
    <properties>
        <sonar.language>java</sonar.language>
        <sonar.host.url>http://sonar.url</sonar.host.url>
        <sonar.login>tokenX</sonar.login>
        <sonar.jacoco.reportMissing.force.zero>true</sonar.jacoco.reportMissing.force.zero>
        <sonar.jacoco.reportPath>${jacoco.destFile}</sonar.jacoco.reportPath>
        <jacoco.destFile>${maven.multiModuleProjectDirectory}/target/jacoco_analysis/jacoco.exec</jacoco.destFile>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <append>true</append>
                            <destFile>${jacoco.destFile}</destFile>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.sonarsource.scanner.maven</groupId>
                    <artifactId>sonar-maven-plugin</artifactId>
                    <version>3.2</version>
                </plugin>
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>0.7.8</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</profile>

Ако добавите този профил към вашия родителски pom и се обадите на mvn clean install sonar:sonar -DrunSonar, получавате пълното покритие.

Магията тук е maven.multiModuleProjectDirectory. Тази папка винаги е папката, в която сте стартирали компилацията на maven.

person Sven Oppermann    schedule 02.02.2017
comment
Това проработи за мен, след като преминах през множество други решения. - person Jimson Kannanthara James; 28.02.2018
comment
Единственият проблем беше, че трябваше да пусна сонар с команда, mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.0.905:sonar -DrunSonar поради A required class was missing while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.0.1:sonar: org/sonar/batch/bootstrapper/IssueListener грешка. - person Jimson Kannanthara James; 28.02.2018
comment
Не използвайте тази магия. Даденото свойство е детайл от изпълнението и не трябва да се разчита на него. -- Екипът на разработчиците на Maven - person Michael-O; 13.02.2019

Конфигурацията, която използвам в pom на моето родителско ниво, където имам отделни фази за изпитване на единица и интеграция.

Конфигурирам следните свойства в родителските свойства на POM

    <maven.surefire.report.plugin>2.19.1</maven.surefire.report.plugin>
    <jacoco.plugin.version>0.7.6.201602180812</jacoco.plugin.version>
    <jacoco.check.lineRatio>0.52</jacoco.check.lineRatio>
    <jacoco.check.branchRatio>0.40</jacoco.check.branchRatio>
    <jacoco.check.complexityMax>15</jacoco.check.complexityMax>
    <jacoco.skip>false</jacoco.skip>
    <jacoco.excludePattern/>
    <jacoco.destfile>${project.basedir}/../target/coverage-reports/jacoco.exec</jacoco.destfile>

    <sonar.language>java</sonar.language>
    <sonar.exclusions>**/generated-sources/**/*</sonar.exclusions>
    <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
    <sonar.coverage.exclusions>${jacoco.excludePattern}</sonar.coverage.exclusions>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.jacoco.reportPath>${project.basedir}/../target/coverage-reports</sonar.jacoco.reportPath>

    <skip.surefire.tests>${skipTests}</skip.surefire.tests>
    <skip.failsafe.tests>${skipTests}</skip.failsafe.tests>

Поставям дефинициите на плъгини под управление на плъгини.

Обърнете внимание, че дефинирам свойство за сигурни (surefireArgLine) и failsafe (failsafeArgLine) аргументи, за да позволя на jacoco да конфигурира javaagent да се изпълнява с всеки тест.

Под управление на плъгини

  <build>
     <pluginManagment>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <fork>true</fork>
                    <meminitial>1024m</meminitial>
                    <maxmem>1024m</maxmem>
                    <compilerArgument>-g</compilerArgument>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <forkCount>4</forkCount>
                    <reuseForks>false</reuseForks>
                    <argLine>-Xmx2048m ${surefireArgLine}</argLine>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                    <excludes>
                        <exclude>**/*IT.java</exclude>
                    </excludes>
                    <skip>${skip.surefire.tests}</skip>
                </configuration>
            </plugin>
            <plugin>
                <!-- For integration test separation -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.19.1</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-junit47</artifactId>
                        <version>2.19.1</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <forkCount>4</forkCount>
                    <reuseForks>false</reuseForks>
                    <argLine>${failsafeArgLine}</argLine>
                    <includes>
                        <include>**/*IT.java</include>
                    </includes>
                    <skip>${skip.failsafe.tests}</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>integration-test</id>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>verify</id>
                        <goals>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <!-- Code Coverage -->
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.plugin.version}</version>
                <configuration>
                    <haltOnFailure>true</haltOnFailure>
                    <excludes>
                        <exclude>**/*.mar</exclude>
                        <exclude>${jacoco.excludePattern}</exclude>
                    </excludes>
                    <rules>
                        <rule>
                            <element>BUNDLE</element>
                            <limits>
                                <limit>
                                    <counter>LINE</counter>
                                    <value>COVEREDRATIO</value>
                                    <minimum>${jacoco.check.lineRatio}</minimum>
                                </limit>
                                <limit>
                                    <counter>BRANCH</counter>
                                    <value>COVEREDRATIO</value>
                                    <minimum>${jacoco.check.branchRatio}</minimum>
                                </limit>
                            </limits>
                        </rule>
                        <rule>
                            <element>METHOD</element>
                            <limits>
                                <limit>
                                    <counter>COMPLEXITY</counter>
                                    <value>TOTALCOUNT</value>
                                    <maximum>${jacoco.check.complexityMax}</maximum>
                                </limit>
                            </limits>
                        </rule>
                    </rules>
                </configuration>
                <executions>
                    <execution>
                        <id>pre-unit-test</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${jacoco.destfile}</destFile>
                            <append>true</append>
                            <propertyName>surefireArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-unit-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${jacoco.destfile}</dataFile>
                            <outputDirectory>${sonar.jacoco.reportPath}</outputDirectory>
                            <skip>${skip.surefire.tests}</skip>
                        </configuration>
                    </execution>
                    <execution>
                        <id>pre-integration-test</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>prepare-agent-integration</goal>
                        </goals>
                        <configuration>
                            <destFile>${jacoco.destfile}</destFile>
                            <append>true</append>
                            <propertyName>failsafeArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-integration-test</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>report-integration</goal>
                        </goals>
                        <configuration>
                            <dataFile>${jacoco.destfile}</dataFile>
                            <outputDirectory>${sonar.jacoco.reportPath}</outputDirectory>
                            <skip>${skip.failsafe.tests}</skip>
                        </configuration>
                    </execution>
                    <!-- Disabled until such time as code quality stops this tripping
                    <execution>
                        <id>default-check</id>
                        <goals>
                            <goal>check</goal>
                        </goals>
                        <configuration>
                            <dataFile>${jacoco.destfile}</dataFile>
                        </configuration>
                    </execution>
                    -->
                </executions>
            </plugin>
            ...

И в раздела за изграждане

 <build>
     <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
        </plugin>

        <plugin>
            <!-- for unit test execution -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
        </plugin>
        <plugin>
            <!-- For integration test separation -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
        </plugin>
        <plugin>
            <!-- For code coverage -->
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
        </plugin>
        ....

И в раздела за отчитане

    <reporting>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-report-plugin</artifactId>
            <version>${maven.surefire.report.plugin}</version>
            <configuration>
                <showSuccess>false</showSuccess>
                <alwaysGenerateFailsafeReport>true</alwaysGenerateFailsafeReport>
                <alwaysGenerateSurefireReport>true</alwaysGenerateSurefireReport>
                <aggregate>true</aggregate>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco.plugin.version}</version>
            <configuration>
                <excludes>
                    <exclude>**/*.mar</exclude>
                    <exclude>${jacoco.excludePattern}</exclude>
                </excludes>
            </configuration>
        </plugin>
     </plugins>
  </reporting>
person sweetfa    schedule 03.05.2016
comment
Виждам, че имате <append>true</append> конфигурацията под prepare-agent секциите ... - person Stewart; 03.05.2016
comment
Акцент. Прочетете коментара ми към друг отговор. Това беше липсващата жизненоважна съставка за мен, която не се намираше в други документи. - person Stewart; 04.05.2016
comment
имате ли връзка към github за това? Искам да направя точно подобни конфигурации - person Rohit Kasat; 05.06.2016
comment
@Rhit - не, не го правя, поне не в публично хранилище. - person sweetfa; 06.06.2016
comment
Това работи много добре със Sonar Qube версия 6.5 (компилация 27846) ... :D Покритието на кода ще бъде правилно показано. - person udoline; 17.08.2018

Тъй като сонарите sonar.jacoco.reportPath, sonar.jacoco.itReportPath и sonar.jacoco.reportPaths са отхвърлени трябва да използвате sonar.coverage.jacoco.xmlReportPaths сега. Това също има известно въздействие, ако искате да конфигурирате многомодулен maven проект със Sonar и Jacoco.

Както @Lonzak посочва, от Sonar 0.7.7 насам можете да използвате целта за агрегиране на отчетите на Sonars. Просто поставете следната зависимост във вашия parent pom:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.5</version>
    <executions>
        <execution>
            <id>report</id>
            <goals>
                <goal>report-aggregate</goal>
            </goals>
            <phase>verify</phase>
        </execution>
    </executions>
</plugin>

Тъй като текущите версии на плъгина jacoco-maven са съвместими с xml-отчетите, това ще създаде за всеки модул в неговата собствена целева папка папка site/jacoco-aggregate, съдържаща jacoco.xml файл.

За да позволите на Sonar да комбинира всички модули, използвайте следната команда:

mvn -Dsonar.coverage.jacoco.xmlReportPaths=full-path-to-module1/target/site/jacoco-aggregate/jacoco.xml,module2...,module3... clean verify sonar:sonar

За да запазя отговора си кратък и точен, не споменах зависимостите maven-surefire-plugin и maven-failsafe-plugin. Можете просто да ги добавите без друга конфигурация:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.2</version>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.22.2</version>
    <executions>
        <execution>
        <id>integration-test</id>
            <goals>
                <goal>integration-test</goal>
            </goals>
        </execution>
    </executions>
</plugin>
person Jacob van Lingen    schedule 28.11.2019

Можете да извикате задача на мравка, наречена сливане на maven, за да поставите всички файлове с покритие (*.exec) заедно в един и същ файл.

Ако изпълнявате модулни тестове, използвайте фазата prepare-package, ако изпълнявате интеграционен тест, използвайте post-integration-test.

Този сайт има пример как извикване на jacoco ant задача в проекта maven

Можете да използвате този обединен файл на сонар.

person Andre Piantino    schedule 23.10.2012

за да имате модулно тестване И интеграционно тестване, можете да използвате maven-surefire-plugin и maven-failsafe-plugin с ограничени включвания/изключвания. Играех си с CDI, докато се свързвах със сонар/jacoco, така че попаднах в този проект:

https://github.com/FibreFoX/cdi-sessionscoped-login/

Може би това ще ви помогне малко. в моя pom.xml използвам "-javaagent" имплицитно, като задам опцията argLine в раздела за конфигурация на посочените добавки за тестване. Изричното използване на ANT в проекти на MAVEN е нещо, което не бих опитал, за мен е твърде много смесване на два свята.

Имам само едномодулен maven проект, но може би ще ви помогне да настроите своя да работи.

забележка: може би не всички maven-плъгини са актуални, може би някои проблеми са коригирани в по-късни версии

person FibreFoX    schedule 20.02.2013
comment
Благодаря за това; Ще разгледам и ще ви кажа как се получава. Може обаче да не е тази седмица :) - person Stewart; 20.02.2013

Тази проба работи много добре за мен:

<plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.2</version>
            <executions>
                <execution>
                    <id>pre-unit-test</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                    <configuration>
                        <destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
                        <propertyName>surefireArgLine</propertyName>
                    </configuration>
                </execution>
                <execution>
                    <id>pre-integration-test</id>
                    <goals>
                        <goal>prepare-agent-integration</goal>
                    </goals>
                    <configuration>
                        <destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
                        <!--<excludes>
                            <exclude>com.asimio.demo.rest</exclude>
                            <exclude>com.asimio.demo.service</exclude>
                        </excludes>-->
                        <propertyName>testArgLine</propertyName>
                    </configuration>
                </execution>
                <execution>
                    <id>post-integration-test</id>
                    <phase>post-integration-test</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile>
                        <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
                    </configuration>
                </execution>
                <execution>
                    <id>post-unit-test</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
                        <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
                    </configuration>
                </execution>
                <execution>
                    <id>merge-results</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>merge</goal>
                    </goals>
                    <configuration>
                        <fileSets>
                            <fileSet>
                                <directory>${project.build.directory}/coverage-reports</directory>
                                <includes>
                                    <include>*.exec</include>
                                </includes>
                            </fileSet>
                        </fileSets>
                        <destFile>${project.build.directory}/coverage-reports/aggregate.exec</destFile>
                    </configuration>
                </execution>
                <execution>
                    <id>post-merge-report</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <dataFile>${project.build.directory}/coverage-reports/aggregate.exec</dataFile>
                        <outputDirectory>${project.reporting.outputDirectory}/jacoco-aggregate</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.18.1</version>
            <configuration>
                <argLine>${surefireArgLine}</argLine>
                <!--<skipTests>${skip.unit.tests}</skipTests>-->
                <includes>
                    <include>**/*Test.java</include>
                    <!--<include>**/*MT.java</include>
                    <include>**/*Test.java</include>-->
                </includes>
            <!--    <skipTests>${skipUTMTs}</skipTests>-->
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.12.4</version>
            <configuration>
                <!--<skipTests>${skipTests}</skipTests>
                <skipITs>${skipITs}</skipITs>-->
                <argLine>${testArgLine}</argLine>
                <includes>
                    <include>**/*IT.java</include>
                </includes>
                <!--<excludes>
                    <exclude>**/*UT*.java</exclude>
                </excludes>-->
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
person SerhatTopkaya    schedule 04.10.2019
comment
Моля, дайте някакво обяснение на отговора си - person mishsx; 04.10.2019
comment
@mishsx Хубава статия за обяснение: natritmeyer .com/howto/ - person SerhatTopkaya; 07.10.2019

Както е посочено в Jacoco Wiki, можете също да генерирате нов модул за отчитане:

Стратегия: Модул със зависимости: Проблемите с агрегаторните проекти могат да бъдат решени с допълнителен модул за отчитане. В многомодулен проект на Maven се дефинира отделен модул, който не допринася с действително съдържание, но създава комбиниран отчет за покритие. Той дефинира зависимост към всички модули, които трябва да бъдат включени в комбинирания отчет. Модулът за отчитане ще бъде изграден след неговите зависимости и ще има достъп до exec файловете, както и до файловете с клас и източник от проекти, от които зависи. Тази стратегия изглежда работи най-добре с текущата архитектура на Maven. От гледна точка на потребителя може да се твърди, че такъв отделен модул би раздул дефиницията на компилация. Или, че отделният модул не може да има подмодули, от които може да консумира exec или class файлове. Въпреки това, в сравнение с другите стратегии, тези недостатъци изглеждат доста незначителни и могат да бъдат третирани по последователен начин.

Това е особено полезно, ако вашата модулация е по-сложна от един родител с някои дъщерни модули.

Вашият докладващ pom може да изглежда така:

 <dependencies>
    <dependency>
        <groupId>org.sonarqube</groupId>
        <artifactId>module1</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.sonarqube</groupId>
        <artifactId>module2</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>report</id>
                    <goals>
                        <goal>report-aggregate</goal>
                    </goals>
                    <phase>verify</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
person Fzum    schedule 25.03.2021