3

我有一份集成测试的代码覆盖率报告。

我确实有集成测试,这些测试在 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。这是因为 Jetty 服务器在 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 服务器以分叉模式启动?

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

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

我的日志说:

[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

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

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

  <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 服务器停止后如何生成报告?

4

1 回答 1

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>

(或者只是省略阶段)它应该可以工作。

于 2015-12-22T16:37:12.080 回答