2013-04-15 2 views
16

Есть ли способ получить покрытие кода с помощью JaCoCo с помощью встроенного экземпляра tomcat7-maven-plugin?Tomcat7 Maven Plugin и JaCoCo

Плагин jacoco-maven сконфигурирован в POM моей WAR для тестирования моих модульных тестов, но я не уверен, как подключить jacoco-агент к встроенному экземпляру Tomcat для тестирования моих интеграционных тестов, которые работают против Tomcat. Учитывая, что экземпляр Tomcat встроен, я не уверен, возможен ли этот подход. Есть ли другой способ сделать это? Вероятно, я могу перейти от использования Tomcat Maven Plugin к использованию Cargo, чтобы получить покрытие, но я предпочел бы придерживаться плагина Tomcat, если это возможно.

Вот несколько соответствующих отрывков из моей POM:

<plugin> 
    <groupId>org.jacoco</groupId> 
    <artifactId>jacoco-maven-plugin</artifactId> 
    <version>0.6.2.201302030002</version> 
    <executions> 
     <execution> 
      <goals> 
       <goal>prepare-agent</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 
<plugin> 
    <artifactId>maven-failsafe-plugin</artifactId> 
    <version>2.14</version> 
    <executions> 
     <execution> 
      <id>integration-tests</id> 
      <goals> 
       <goal>integration-test</goal> 
       <goal>verify</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 
<plugin> 
    <groupId>org.apache.tomcat.maven</groupId> 
    <artifactId>tomcat7-maven-plugin</artifactId> 
    <version>2.1</version> 
    <configuration> 
     <systemProperties> 
      <!-- as expected, this system property doesn't work since Tomcat is embedded, but this is the type of config I'm looking for --> 
      <JAVA_OPTS>-javaagent:${project.build.directory}/${jacoco.jar}=destfile=${project.build.directory}/jacoco.exec,append=true</JAVA_OPTS> 
     </systemProperties> 
    </configuration> 
    <executions> 
     <execution> 
      <id>tomcat-startup</id> 
      <goals> 
       <goal>run-war-only</goal> 
      </goals> 
      <phase>pre-integration-test</phase> 
      <configuration> 
       <fork>true</fork> 
      </configuration> 
     </execution> 
     <execution> 
      <id>tomcat-shutdown</id> 
      <goals> 
       <goal>shutdown</goal> 
      </goals> 
      <phase>post-integration-test</phase> 
     </execution> 
    </executions> 
</plugin> 

Версии: Maven 3.0.4, Tomcat Maven Plugin 2.1, Jacoco 0.6.2.201302030002, Java 7

+0

Просто наткнулся на [MTOMCAT-83] (https://issues.apache.org/jira/browse/MTOMCAT-83), который, похоже, описывает эту же проблему. – shelley

ответ

1

Вам не нужно пройти JAVA_OPTStomcat embedded если вы используете maven-failafe-plugin (или maven-surefire-plugin), чтобы запустить ваш интеграционный тест. Это связано с тем, что tomcat встроен в один и тот же процесс maven-failafe-plugin.

Так что, когда jacoco-Maven-плагин выполнить подготовки агента он устанавливает argLine что maven-failsafe-plugin uses too.

Я создал проект, чтобы проверить это, ниже часть П:

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.jacoco</groupId> 
      <artifactId>jacoco-maven-plugin</artifactId> 
      <version>0.6.2.201302030002</version> 
      <executions> 
       <execution> 
        <goals> 
         <goal>prepare-agent</goal> 
        </goals> 
        <configuration> 
         <includes> 
          <include>my.project.package.only.*</include> 
         </includes> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 
     <plugin> 
      <groupId>org.apache.tomcat.maven</groupId> 
      <artifactId>tomcat7-maven-plugin</artifactId> 
      <version>2.1</version> 
      <executions> 
       <execution> 
        <id>tomcat-startup</id> 
        <goals> 
         <goal>run-war-only</goal> 
        </goals> 
        <phase>pre-integration-test</phase> 
        <configuration> 
         <fork>true</fork> 
        </configuration> 
       </execution> 
       <execution> 
        <id>tomcat-shutdown</id> 
        <goals> 
         <goal>shutdown</goal> 
        </goals> 
        <phase>post-integration-test</phase> 
       </execution> 
      </executions> 
     </plugin> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-failsafe-plugin</artifactId> 
      <executions> 
       <execution> 
        <id>integration-tests</id> 
        <phase>integration-test</phase> 
        <goals> 
         <goal>integration-test</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 
     <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>selenium-maven-plugin</artifactId> 
      <version>2.3</version> 
      <executions> 
       <execution> 
        <id>start</id> 
        <phase>pre-integration-test</phase> 
        <goals> 
         <goal>start-server</goal> 
        </goals> 
        <configuration> 
         <background>true</background> 
         <logOutput>true</logOutput> 
         <multiWindow>true</multiWindow> 
        </configuration> 
       </execution> 
       <execution> 
        <id>stop</id> 
        <phase>post-integration-test</phase> 
        <goals> 
         <goal>stop-server</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 
    </plugins> 
+0

Конфигурация JAVA_OPTS выше для плагина для груза или tomcat? Как уже упоминалось в моем первоначальном вопросе и проиллюстрированном на моей POM, я уже пытался установить JAVA_OPTS для Maven Tomcat Plugin, но не считаю, что он работает для встроенных серверов, поэтому я не совсем уверен, что здесь предлагается. – shelley

+0

Я уже видел это сообщение SO и тестировал его, но он не работал (как и ожидалось, за [этот пост] (http://tomcat.10.x6.nabble.com/Tomcat-7-Maven-Plugin-set -MaxPermSize-td4991157.html), [этот вопрос] (https://issues.apache.org/jira/browse/MTOMCAT-83) и с учетом того, что он встроен). Можете ли вы фактически запустить jacoco, как показано выше, с помощью Maven Tomcat Plugin, или вы просто предлагаете, чтобы конфигурация, которую я опубликовал в начальном вопросе _should_, работал? – shelley

+1

Агент даже не запускается. Плагин Tomcat работает так, как ожидалось; Я использовал его таким образом, чтобы запускать свои интеграционные тесты какое-то время, но просто попытался добавить jacoco к нему. – shelley

0

я решил проблемы при настройке JaCoCo агент со встроенным Tomcat, отключив инструменты, а затем просто разместив агент JaCoCo на пути Tomcat (зависимость плагина) и добавив файл jacoco-agent.properties.

я поставил рабочую конфигурацию в моем блоге:

http://burkond.blogspot.de/2014/05/selenium-in-sonar-code-coverage-metrics.html

7

Я знаю, что его было некоторое время, так как вопрос был отправлен, но я не чувствую, что ответ действительно обратился корень проблемы. Покрытие кода может работать с отказоустойчивым или надежным при выполнении тестов внутри этих плагинов. Однако, если вы просто хотите контролировать tomcat с jacoco, чтобы получить отчет о покрытии, текущая информация не предусматривает этого. Я обнаружил, что Tomcat7-maven-plugin не позволяет вам вводить javaagent для jacoco, просто предоставляя JAVA_OPTS. Перейдя на груз, я смог сделать это так.

<plugin> 
    <groupId>org.jacoco</groupId> 
    <artifactId>jacoco-maven-plugin</artifactId> 
    <version>0.7.2.201409121644</version> 
    <configuration> 
     <destFile>${sonar.jacoco.reportPath}</destFile> 
     <dataFile>${sonar.jacoco.reportPath}</dataFile> 
     <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory> 
     <classDumpDir>${project.reporting.outputDirectory}/jacoco-it/classes</classDumpDir> 
     <skip>${skipITs}</skip> 
    </configuration> 
    <executions> 
     <execution> 
      <id>jacoco-agent</id> 
      <phase>pre-integration-test</phase> 
      <goals> 
       <goal>prepare-agent</goal> 
      </goals> 
      <configuration> 
       <destFile>${sonar.jacoco.reportPath}</destFile> 
       <propertyName>jacoco.agent.itArgLine</propertyName> 
      </configuration> 
     </execution> 
     <execution> 
      <id>jacoco-report</id> 
      <phase>post-integration-test</phase> 
      <goals> 
       <goal>dump</goal> 
       <goal>report</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 
    <plugin> 
    <groupId>org.codehaus.cargo</groupId> 
    <artifactId>cargo-maven2-plugin</artifactId> 
    <version>1.4.11</version> 
    <configuration> 
     <skip>${skipITs}</skip> 
     <container> 
      <containerId>tomcat7x</containerId> 
      <zipUrlInstaller> 
       <url>http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.16/bin/apache-tomcat-7.0.16.zip 
       </url> 
       <downloadDir>${project.build.directory}/downloads</downloadDir> 
       <extractDir>${project.build.directory}/extracts</extractDir> 
      </zipUrlInstaller> 
      <dependencies> 
       <dependency> 
        <groupId>ojdbc</groupId> 
        <artifactId>ojdbc6</artifactId> 
       </dependency> 
      </dependencies> 
     </container> 
     <configuration> 
      <home>${project.build.directory}/catalina-base</home> 
      <properties> 
       <cargo.jvmargs>${jacoco.agent.itArgLine},output=tcpserver,port=6300 -Drunmode=TEST</cargo.jvmargs> 
       <cargo.servlet.port>9090</cargo.servlet.port> 
      </properties> 
      <configfiles> 
       <configfile> 
        <file>${basedir}/src/test/conf/context.xml</file> 
        <todir>conf/Catalina/localhost/</todir> 
        <tofile>context.xml.default</tofile> 
       </configfile> 
      </configfiles> 
     </configuration> 
    </configuration> 
    <executions> 
     <execution> 
      <id>start-tomcat</id> 
      <phase>pre-integration-test</phase> 
      <goals> 
       <goal>start</goal> 
      </goals> 
     </execution> 
     <execution> 
      <id>stop-tomcat</id> 
      <phase>post-integration-test</phase> 
      <goals> 
       <goal>stop</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 

важные детали:

  1. <plugin><groupId>org.jacoco</groupId> ...<propertyName>jacoco.agent.itArgLine</propertyName>
  2. <cargo.jvmargs>${jacoco.agent.itArgLine},output=tcpserver,port=6300 </cargo.jvmargs>

Когда целевой отчет запускается на jacoco плагин создаст директорию в $ {projectbase}/цель /site/jacoco-it/index.html с вашим докладом о покрытии.Я использую это с плагином soapui-maven, но его можно использовать и с selenium-maven-plugin.

+0

Благодарим вас за ответ. Как уже упоминалось в моем первоначальном вопросе, я знаю, что могу выполнить это с помощью груза (и это было моим временным решением), но я хотел бы знать, как это сделать с помощью Tomcat7-maven-plugin. – shelley

+0

@shelley Вы не можете подключить jacoco-агент, используя модуль tomcat7-maven-plugin. Вы должны указать проблему с этим проектом в этом отношении. Когда я сделал это для своего проекта почти 2 года назад, мне пришлось подключиться к плацдарму причала. Теперь это не работает с Java 8. Похоже, я буду изучать следующий метод в этом ответе. –

+0

Разве это не приведет к ошибке «Недостаточно памяти»? –

0

У меня была точно такая же проблема, и единственное решение, которое я нашел в том, чтобы установить MAVEN_OPTS ранее для сборки Maven (например, в командной строке или в конфигурации задания Jenkins):

export MAVEN_OPTS=-javaagent:~/.m2/repository/org/jacoco/org.jacoco.agent/0.7.4.201502262128/org.jacoco.agent-0.7.4.201502262128-runtime.jar=destfile=./target/jacoco.exec,append=true 

Это добавит агент jacoco во встроенный экземпляр tomcat, который сообщит результаты покрытия в заданный destfile.

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

mvn org.apache.maven.plugins:maven-dependency-plugin:2.8:get -Dartifact=org.jacoco:org.jacoco.agent:0.7.4.201502262128:jar:runtime 

Во-вторых, убедитесь, что путь к файлу jacoco.exec правильно. В моем случае у меня уже есть файл jacoco.exec в целевой папке, который содержит результаты единичных тестов. append=true гарантирует, что единичные и интеграционные тесты будут объединены.

+0

, выполняющий весь процесс maven с помощью агента jacoco, не рекомендуется. И вам нужно будет указать версию вручную (и ссылаться на ваш maven repo напрямую), а не просто использовать плагин ... – olivervbk

0

мне удалось это сделать, и это включает в себя некоторые мастерить с привередливы вещи:

  • сервер/контейнер должен быть на отдельном JVM, который может принимать аргументы (jacoco-агент). Груз с использованием встроенных контейнеров, похоже, не работал, и было больно отлаживать ...
  • jvm с jacoco - ему нужно остановиться перед анализом jacoco (duh!), Но зарегистрировать контейнер-стоп и jacoco-отчет по после интеграции -test не гарантирует этого ... (опция tcpdump и т. д. в предыдущем ответе возникла эта проблема)
  • определение случайных портов для сервера/контейнера упрощает интеграцию с непрерывной интеграцией
  • phantomjs является дополнительным;)
  • jacoco следует использовать в качестве интеграции-подготовки и интеграции отчетов для интеграции-теста (на самом деле не имеет значения)

Должен быть запущен как 'МВН чистой проверяй'

Pom:

<plugin> 
    <groupId>org.jacoco</groupId> 
    <artifactId>jacoco-maven-plugin</artifactId> 
    <version>0.7.4.201502262128</version> 
    <executions> 
     <!-- unit test coverage --> 
     <execution> 
      <id>jacoco-pre-unit-test</id> 
      <goals> 
       <goal>prepare-agent</goal> 
      </goals> 
      <configuration> 
       <destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile> 
       <propertyName>jacoco.ut.argLine</propertyName> 
      </configuration> 
     </execution> 
     <execution> 
      <id>jacoco-post-unit-test</id> 
      <phase>test</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> 

     <!-- integration test coverage --> 
     <execution> 
      <id>jacoco-pre-integration-test</id> 
      <phase>pre-integration-test</phase> 
      <goals> 
       <goal>prepare-agent-integration</goal> 
      </goals> 
      <configuration> 
       <destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile> 
       <propertyName>jacoco.it.argLine</propertyName> 
      </configuration> 
     </execution> 
     <execution> 
      <id>jacoco-post-integration-test</id> 
      <phase>post-integration-test</phase> 
      <goals> 
       <goal>report-integration</goal> 
      </goals> 
      <configuration> 
       <dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile> 
       <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 
<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>sonar-maven-plugin</artifactId> 
    <version>2.6</version> 
</plugin> 

<!-- Installs PhantomJS so it doesn't have to be pre-installed --> 
<plugin> 
    <groupId>com.github.klieber</groupId> 
    <artifactId>phantomjs-maven-plugin</artifactId> 
    <version>0.4</version> 
    <executions> 
     <execution> 
      <!-- should be post-integration-test ? --> 
      <phase>test</phase> 
      <goals> 
       <goal>install</goal> 
      </goals> 
     </execution> 
    </executions> 
    <configuration> 
     <version>1.9.7</version> 
    </configuration> 
</plugin> 

<!-- Get two free ports for our test server to use --> 
<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>build-helper-maven-plugin</artifactId> 
    <version>1.6</version> 
    <configuration> 
     <portNames> 
      <portName>jetty.port</portName> 
      <portName>jetty.port.stop</portName> 
     </portNames> 
    </configuration> 
    <executions> 
     <execution> 
      <id>reserve-port</id> 
      <phase>test</phase> 
      <goals> 
       <goal>reserve-network-port</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 

<!-- Run tests (UT) --> 
<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>2.18.1</version> 
    <configuration> 
     <argLine>${jacoco.ut.argLine}</argLine> 
     <skipTests>${skip.unit.tests}</skipTests> 
     <testFailureIgnore>true</testFailureIgnore> 
     <excludes> 
      <!-- no UT execution, to test only IT 
      <exclude>**/<remove this>*Test.java</exclude> --> 
     </excludes> 
    </configuration> 
</plugin> 

<!-- Use failsafe to run our integration tests --> 
<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-failsafe-plugin</artifactId> 
    <version>2.17</version> 
    <configuration> 
     <systemPropertyVariables> 
      <!-- pass these values to the test classes --> 
      <phantomjs.binary>${phantomjs.binary}</phantomjs.binary> 
      <jetty.port>${jetty.port}</jetty.port> 
     </systemPropertyVariables> 
    </configuration> 
    <executions> 
     <execution> 
      <id>integration-test</id> 
      <goals> 
       <goal>integration-test</goal> 
       <goal>verify</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 

<plugin> 
    <groupId>org.codehaus.cargo</groupId> 
    <artifactId>cargo-maven2-plugin</artifactId> 
    <version>1.4.16</version> 
    <configuration> 
     <skip>${skipITs}</skip> 
     <container> 
      <containerId>tomcat8x</containerId> 
      <zipUrlInstaller> 
       <!-- did not work with 'https'. Certificate problem? --> 
       <url>http://archive.apache.org/dist/tomcat/tomcat-8/v8.0.26/bin/apache-tomcat-8.0.26.zip</url> 
       <downloadDir>${project.build.directory}/downloads</downloadDir> 
       <extractDir>${project.build.directory}/extracts</extractDir> 
      </zipUrlInstaller> 
     </container> 
     <configuration> 
      <home>${project.build.directory}/catalina-base</home> 
      <properties> 
       <cargo.jvmargs>${jacoco.it.argLine}</cargo.jvmargs> 
       <cargo.servlet.port>${jetty.port}</cargo.servlet.port> 
       <!-- <cargo.logging>high</cargo.logging> --> 
      </properties> 
     </configuration> 
    </configuration> 
    <executions> 
     <execution> 
      <id>cargo-start-tomcat</id> 
      <phase>pre-integration-test</phase> 
      <goals> 
       <goal>start</goal> 
      </goals> 
     </execution> 
     <execution> 
      <id>cargo-stop-tomcat</id> 
      <phase>integration-test</phase> 
      <goals> 
       <goal>stop</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin>