Как настроить многомодульный 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 docs относятся к проект 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
Чудесный! Это сработало. Наконец-то! Я думаю, что магия, которой не хватало жизненного заклинания, которое мне не хватало, была ‹append› истинной ‹/append› - 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 /Release+4.3+Upgrade+Notes - 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 ..) находится в Ираке, Сирии и т. Д. .. Можно ли получить многомодульное покрытие при выполнении на нем интеграционных тестов? Jenkins и Sonar также находятся на разных серверах.

да. Вы должны использовать агент jacoco, который работает в режиме output=tcpserver, jacoco ant lib. . В основном два jars. Это даст вам 99% успеха.

Как работает jacoco agent?

Вы добавляете строку

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

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

Могу ли я сбросить агент jacoco, чтобы он начал сбор данных о выполнении только с момента запуска моего теста?

Да, для этого вам понадобится jacocoant.jar и скрипт сборки ant, расположенный в вашем рабочем пространстве jenkins.

Итак, в основном то, что мне нужно от http://www.eclemma.org/jacoco/, - это jacocoant.jar, расположенный в моем рабочем пространстве jenkins, и jacocoagent.jar, расположенный на моей виртуальной машине сервера приложений?

Верно.

Я не хочу использовать ant, я слышал, что плагин jacoco maven тоже может делать все то же самое.

Это неправильно, плагин jacoco maven может собирать данные модульных тестов и некоторые данные интеграционных тестов (см. Arquillian Jacoco), но если у вас, например, есть тесты в виде отдельной сборки в jenkins, и вы хотите показать многомодульное покрытие, я не вижу, как плагин maven может вам помочь.

Что именно производит агент jacoco?

Только данные о покрытии в формате .exec. После этого сонар сможет это прочитать.

Нужно ли jacoco знать, где находятся мои классы Java?

Нет, гидролокатор, но не jacoco. Когда вы делаете 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. Вызвать цель муравья jacocoReport, чтобы получить отчет

Если все в порядке, вы увидите it-jacoco.exec в рабочей области сборки.

Посмотрите на снимок экрана, у меня также установлено ant в моем рабочем пространстве в $WORKSPACE/tools/ant каталоге, но вы можете использовать тот, который установлен в ваших jenkins.

введите описание изображения здесь

Как протолкнуть этот отчет в сонар?

Maven sonar:sonar выполнит задание (не забудьте настроить его), направив его на главный файл 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 

Корневой 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>

Я также нашел Сообщение в блоге Петри Кайнулайненса« Создание отчетов о покрытии кода для модульных и интеграционных тестов с помощью подключаемого модуля 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 вы должны установить свойство в графическом интерфейсе администрирования:

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 содержат данные о покрытии только для зависимостей.

Вместе эти два типа отчетов предоставляют полные данные о покрытии для сонара.

Есть одно небольшое ограничение: вы должны иметь возможность писать отчет в родительском каталоге проекта (при наличии разрешения). Или вы можете установить свойство 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>

Я помещаю определения плагинов в управление плагинами.

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

Под pluginManagement

  <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, вы можете использовать цель увеличения отчета сонара. Просто вставьте в родительский объект следующую зависимость:

<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-plugin совместимы с 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. Однако по сравнению с другими стратегиями эти недостатки кажутся незначительными, и с ними можно последовательно справляться.

Это особенно полезно, если ваша модульность сложнее, чем один родитель с некоторыми дочерними модулями.

Ваш отчет может выглядеть примерно так:

 <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