2017-02-17 39 views
1

У меня есть несколько большой мультимодульный проект Maven. У меня есть модульные тесты в каждом модуле, который обрабатывается Jacoco. У меня есть отдельный дочерний модуль, который выполняет «слияние» и «агрегацию отчетов», и это, по-видимому, генерирует данные. Я даже использую сгенерированные данные в SonarQube. Большинство моих тестов используют PowerMock, и я использую автономную аппаратуру.jacoco только показывает покрытие для классов в том же модуле

Однако, посмотрев ближе к данным покрытия, я вижу, что он не учитывает данные о покрытии для классов и методов, которые, как я знаю, выполняются во время тестов. Шаблон, который я вижу в каждом модуле, состоит в том, что он сообщает только о покрытии для одного класса в каждом модуле, который является классом, фактически действующим в текущем модуле. Почти все тесты также вызывают другие классы в других модулях в сборке, и охват для этих классов никогда не сообщается.

следующие конфигурации плагинов в родительском ПОМ, используемый каждым ребенком модуля:

<plugin> 
    <groupId>org.jacoco</groupId> 
    <artifactId>jacoco-maven-plugin</artifactId> 
    <version>0.7.8</version> 
    <executions> 
     <execution> 
      <id>default-instrument</id> 
      <goals> 
       <goal>instrument</goal> 
      </goals> 
     </execution> 
     <execution> 
      <id>default-restore-instrumented-classes</id> 
      <goals> 
       <goal>restore-instrumented-classes</goal> 
      </goals> 
     </execution> 
     <execution> 
      <id>default-report</id> 
      <phase>prepare-package</phase> 
      <goals> 
       <goal>report</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 
<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>2.19.1</version> 
    <configuration> 
     <argLine>-Xmx1024m</argLine> 
     <includes> 
      <include>**/*Test.java</include> 
     </includes> 
     <systemPropertyVariables> 
      <jacoco-agent.destfile>${project.build.directory}/jacoco.exec</jacoco-agent.destfile> 
      <running-unit-test>true</running-unit-test> 
     </systemPropertyVariables> 
    </configuration> 
</plugin> 

Когда я проверить сгенерированные результаты HTML для каждого модуля, я считаю, что это только передает результаты для одного класса в текущий модуль, а не данные для классов в других модулях. Из этого я бы предположил, что то, как я делаю «слияние» и «агрегация отчетов» в отдельном дочернем модуле, вероятно, не имеет отношения к этой проблеме.

Сгенерированный файл «jacoco.exec» является двоичным, но я попытался «пропустить» один из одного модуля, чтобы увидеть, какой текст ascii был виден, и он показал только одно вхождение чего-либо, похожего на имя файла, и это было единственное имя файла, о котором сообщается в отчете по охвату HTML для этого модуля.

Я не знаю, какую другую информацию я могу сообщить.

Update:

Я предполагаю, что я могу видеть довольно ясно теперь, когда Surefire запускает тесты блока, он использует инструментальные классы из текущего модуля, но uninstrumented классов от Maven артефактов. Вот почему я вижу только охват классов в текущем модуле.

Так что мне кажется, что мне нужно указать, что папка «target/generated-classes/jacoco» для каждого модуля, от которого зависит текущий модуль, добавляется к пути к классам, который использует верный огонь. Я не вижу способа сделать это.

В качестве альтернативы, я вижу, что цель «инструмента» имеет элемент конфигурации «включает». Должен ли я указывать пути ко всем каталогам «цель/классы» для каждого из модулей, от которых зависит текущий модуль?

ответ

0

Для записи покрытия кода для некоторого класса требуется его инструментарий. Цель instrument выполняет приборы классов текущего модуля.

все тесты также взывать к другим классам в других модулях

так, что те, которые не инструментированные. И если я правильно понял, то именно те, для которых вам не хватает покрытия.

Если вы не используете PowerMock для классов, которые поступают из других модулей, но только для классов в текущем модуле, то вы можете комбинировать автономную аппаратуру с помощью агента «на лету». Но в этом случае убедитесь, что классы, управляемые в автономном режиме, явно исключены из инструментария агентом, иначе агент будет метать IllegalStateException: Class ... is already instrumented.

Если вы используете PowerMock для классов, которые поступают из других модулей, то это становится более сложным из-за строгости Maven в отношении манипуляций с классами и зависимостями. И я сомневаюсь, что это может быть легко достигнуто с помощью одного mvn Comand, однако представляется возможным использование большие:

  1. инструмента и запустить тесты, но не использовать restore-instrumented-classes
  2. восстановления классов и генерировать отчет (ы)

К сожалению, вы не указали полный пример (https://stackoverflow.com/help/mcve), и у меня нет времени подготовить полный пример, чтобы проверить этот подход прямо сейчас.

В качестве побочного примечания: невозможность просто использовать агент происходит из-за того, что PowerMock обходит любого агента и считывает файлы классов с диска.

+0

Я думаю, что рассмотрю это с помощью нескольких среднесрочных стратегий: 1. Пока мы используем PowerMock с автономной аппаратурой, принимаем, что модульные тесты в модуле «foo» будут отображаться только для этого модуля, 2. Write unit тесты в другом модуле для классов, которые не рассматриваются, 3. Замените один механизм, который заставляет использовать PowerMock использовать Factory, а затем изменять эти тесты для использования Mockito и онлайн-инструментов. –