在运行集成测试之前,如何让Maven构建等待Jetty服务器以分叉模式启动?

时间:2015-12-17 19:57:48

标签: jacoco jacoco-maven-plugin

我通过集成测试报告了代码覆盖率。

我有集成测试,这些测试在Maven构建中成功运行。

当我点击HTML报告右上角的“会话”链接时,我可以在列表中看到我的测试类,但是我看不到现在由测试运行的主要类,以及所有覆盖报告百分比为零。

作为旁注,我的单元测试覆盖率正常,百分比显示正常。

我的配置如下:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>
    <configuration>
      <argLine>${surefireArgLine}</argLine>
      <excludes>
        <exclude>**/integrationtest/*.java</exclude>
      </excludes>
    </configuration>
  </plugin>

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.18.1</version>
     <configuration>
       <argLine>${failsafeArgLine}</argLine>
       <skipTests>${skipIntegrationTests}</skipTests>
      <includes>
        <include>**/integrationtest/*.java</include>
      </includes>
    </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>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.5.201505241946</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>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>
      <execution>
        <id>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>failsafeArgLine</propertyName>
        </configuration>
      </execution>
      <execution>
        <id>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.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.2.2.v20140723</version>
    <configuration>
      <httpConnector>
        <port>${jetty.port}</port>
      </httpConnector>
      <scanIntervalSeconds>10</scanIntervalSeconds>
      <stopPort>8805</stopPort>
      <stopKey>STOP</stopKey>
    </configuration>
    <executions>
      <execution>
        <id>start-jetty</id>
        <phase>pre-integration-test</phase>
        <goals>
          <goal>stop</goal> <!-- stop any stray process that has been running since before -->
          <goal>run-forked</goal>
        </goals>
        <configuration>
          <scanIntervalSeconds>0</scanIntervalSeconds>
          <daemon>true</daemon>
          <waitForChild>false</waitForChild>
          <maxStartupLines>200</maxStartupLines>
          <jvmArgs>${failsafeArgLine} -Djetty.port=${jetty.port}</jvmArgs>
        </configuration>
      </execution>
      <execution>
        <id>stop-jetty</id>
        <phase>post-integration-test</phase>
        <goals>
          <goal>stop</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

注意JaCoCo插件是如何在之前定义的。

控制台日志显示连接尝试失败的日志。集成测试无法连接到localhost。这是因为Jetven服务器在Maven运行测试之前没有时间启动。

org.apache.http.conn.HttpHostConnectException: Connection to http://localhost:8888 refused

这是另一个控制台日志位:

[STDERR] 2015-12-21 09:49:43.486:WARN:oejuc.AbstractLifeCycle:main: FAILED ServerConnector@2cd9b65d{HTTP/1.1}{0.0.0.0:8080}: java.net.BindExcep
tion: Address already in use
[STDERR] java.net.BindException: Address already in use
[STDERR]        at sun.nio.ch.Net.bind0(Native Method)
[STDERR]        at sun.nio.ch.Net.bind(Net.java:436)
[STDERR]        at sun.nio.ch.Net.bind(Net.java:428)
[STDERR]        at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
[STDERR]        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
[STDERR]        at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:277)
[STDERR]        at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
[STDERR]        at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:216)
[STDERR]        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
[STDERR]        at org.eclipse.jetty.maven.plugin.MavenServerConnector.doStart(MavenServerConnector.java:120)
[STDERR]        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
[STDERR]        at org.eclipse.jetty.server.Server.doStart(Server.java:359)
[STDERR]        at org.eclipse.jetty.maven.plugin.JettyServer.doStart(JettyServer.java:76)
[STDERR]        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
[STDERR]        at org.eclipse.jetty.maven.plugin.Starter.run(Starter.java:401)
[STDERR]        at org.eclipse.jetty.maven.plugin.Starter.main(Starter.java:516)
[STDERR] 2015-12-21 09:49:43.486:WARN:oejuc.AbstractLifeCycle:main: FAILED org.eclipse.jetty.maven.plugin.MavenServerConnector@630b8061: java.net.BindException: Address already in use
[STDERR] java.net.BindException: Address already in use
[STDERR]        at sun.nio.ch.Net.bind0(Native Method)
[STDERR]        at sun.nio.ch.Net.bind(Net.java:436)

为目标设置start值而不是run-forked,测试运行正常。但我需要将其作为代码覆盖率报告的run-forked

使用<waitForChild>false</waitForChild>选项没有改变任何问题。

如何在运行集成测试之前让Maven构建等待Jetty服务器以分叉模式启动?

更新:我可以让Maven构建等待Jetty服务器以fork模式启动,并使用以下<maxStartupLines>200</maxStartupLines>选项。

但是现在,报告中没有看到我的集成测试,尽管它们运行正常。

我的日志说:

[INFO] --- jacoco-maven-plugin:0.7.5.201505241946:prepare-agent-integration (pre-integration-test) @ rest ---
[INFO] failsafeArgLine set to -javaagent:/home/stephane/.m2/repository/org/jacoco/org.jacoco.agent/0.7.5.201505241946/org.jacoco.agent-0.7.5.201505241946-runtime.jar=destfile=/home/stephane/source/...-rest/rest/target/coverage-reports/jacoco-it.exec

[INFO] <<< jetty-maven-plugin:9.2.2.v20140723:run-forked (start-jetty) @ rest <<<
[INFO] 
[INFO] --- jetty-maven-plugin:9.2.2.v20140723:run-forked (start-jetty) @ rest ---
[INFO] Configuring Jetty for project: Rest
[INFO] webAppSourceDirectory not set. Trying src/main/webapp
[INFO] Reload Mechanic: automatic
[INFO] Classes = /home/stephane/source/...-rest/rest/target/classes
[INFO] Context path = /
[INFO] Tmp directory = /home/stephane/source/...-rest/rest/target/tmp
[INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml
[INFO] Web overrides =  none
[INFO] web.xml file = file:/home/stephane/source/...-rest/rest/src/main/webapp/WEB-INF/web.xml
[INFO] Webapp directory = /home/stephane/source/...-rest/rest/src/main/webapp

[INFO] Forked process starting
[INFO] Forked process started.

更新:如果我运行Maven命令mvn jacoco:report-integration,控制台会抱怨缺少数据文件:

[INFO] --- jacoco-maven-plugin:0.7.5.201505241946:report-integration (default-cli) @ rest ---
[INFO] Skipping JaCoCo execution due to missing execution data file:/home/stephane/source/...-rest/rest/target/jacoco-it.exec

实际上,数据文件在pom.xml文件中指定为<dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile>

为什么它被查询为jacoco-it.exec而不是coverage-reports/jacoco-it.exec

是否因为在Jetty服务器有时间停止并生成数据文件之前生成了JaCoCo报告?但为什么不同的文件路径呢?如何告诉JaCoCo报告等待它?

更新:我在集成测试的stopWait目标中添加了stop 1:

  <execution>
    <id>stop-jetty</id>
    <phase>post-integration-test</phase>
    <goals>
      <goal>stop</goal>
    </goals>
    <configuration>
      <stopWait>1</stopWait>
    </configuration>
  </execution>

但它没有改变这个问题。

更新:使用-X选项运行构建显示以下内容:

[INFO] 
[INFO] --- jacoco-maven-plugin:0.7.5.201505241946:report-integration (post-integration-test) @ rest ---
[DEBUG] Configuring mojo org.jacoco:jacoco-maven-plugin:0.7.5.201505241946:report-integration from plugin realm ClassRealm[plugin>org.jacoco:ja
coco-maven-plugin:0.7.5.201505241946, parent: sun.misc.Launcher$AppClassLoader@5c647e05]
[DEBUG] Configuring mojo 'org.jacoco:jacoco-maven-plugin:0.7.5.201505241946:report-integration' with basic configurator -->
[DEBUG]   (f) dataFile = /home/stephane/source/...-rest/rest/target/coverage-reports/jacoco-it.exec
[DEBUG]   (f) outputDirectory = /home/stephane/source/...-rest/rest/target/site/jacoco-it
[DEBUG]   (f) outputEncoding = UTF-8
[DEBUG]   (f) project = MavenProject: no.....db:rest:1.40.0-SNAPSHOT @ /home/stephane/source/...-rest/rest/pom.xml
[DEBUG]   (f) skip = false
[DEBUG]   (f) sourceEncoding = UTF-8
[DEBUG] -- end configuration --
[INFO] Analyzed bundle 'Rest' with 50 classes
[INFO] 
[INFO] --- jetty-maven-plugin:9.2.2.v20140723:stop (stop-jetty) @ rest ---
[DEBUG] Configuring mojo org.eclipse.jetty:jetty-maven-plugin:9.2.2.v20140723:stop from plugin realm ClassRealm[plugin>org.eclipse.jetty:jetty-maven-plugin:9.2.2.v20140723, parent: sun.misc.Launcher$AppClassLoader@5c647e05]
[DEBUG] Configuring mojo 'org.eclipse.jetty:jetty-maven-plugin:9.2.2.v20140723:stop' with basic configurator -->
[DEBUG]   (s) stopKey = STOP
[DEBUG]   (s) stopPort = 8805
[DEBUG]   (f) stopWait = 1
[DEBUG] -- end configuration --
[INFO] Waiting 1 seconds for jetty to stop
[INFO] Server reports itself as stopped

这告诉我在Jetty服务器停止之前正在生成报告。如果是这种情况,那就是错误的。如何在Jetty服务器停止后生成报告?

1 个答案:

答案 0 :(得分:0)

http://eclemma.org/jacoco/trunk/doc/report-integration-mojo.html上阅读了一些有关该插件的内容之后,我注意到它说:

  

默认情况下绑定到生命周期阶段:验证。

所以,改为:

    <execution>
        <id>post-integration-test</id>
        <phase>verify</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>

(或者只是遗漏相位)它应该可以工作。