【问题标题】:Integration testing with maven: run jar before tests and terminate after使用 maven 进行集成测试:在测试之前运行 jar 并在之后终止
【发布时间】:2014-04-17 11:19:54
【问题描述】:

我有一个可运行的 jar,我想在我的集成测试开始之前(pre-integration-test)在新进程中运行它,并在我的集成测试完成后终止它(post-integration-test)。

我可以使用maven-antrun-pluginexec-maven-pluginpre-integration-test 上启动新进程,但如何终止它?

对于我想要实现的目标,也许有更好的解决方案?

PS:我在 Windows 和 Linux 上构建我的项目,所以可移植性对我来说很重要。

【问题讨论】:

  • 使用故障保护,阴影 jar 将在其 jvm 中运行,测试完成后故障安全将关闭该 jvm
  • @guido 不确定我是否理解您的建议。如何使用故障保护来晒太阳?

标签: java maven testing integration-testing


【解决方案1】:

您可以使用 BV 开源的maven-process-plugin 分别启动和停止集成前和集成后阶段的任何进程。自述文件中有一个示例可以完全满足您的要求(启动一个可运行的 jar)。希望对您有所帮助。

主要思想是编写一个具有两个目标的 maven 插件 - 启动和停止。 Start 在您的预集成阶段运行并运行您想要运行的任何进程。 Java 的进程构建器可用于启动进程,如运行 jar 等。将启动的进程存储在数据结构中,如 Map 或 Stack。 “停止”将停止它已启动的所有进程。由于这是一个如此普遍的问题,我建议使用上述插件来轻松启动和停止任何进程以进行集成测试。只需添加以下插件:

<plugin>
        <groupId>com.bazaarvoice.maven.plugins</groupId>
        <artifactId>process-exec-maven-plugin</artifactId>
        <version>0.4</version>
        <executions>
            <!--Start process-->
            <execution>
                <id>start-jar</id>
                <phase>pre-integration-test</phase>
                <goals><goal>start</goal></goals>
                <configuration>
                    <workingDir>app</workingDir>
                    <arguments>
                        <argument>java</argument>
                        <argument>-jar</argument>
                        <argument>app.jar</argument>
                    </arguments>
                </configuration>
            </execution>
            <!--Stop Process-->
            <execution>
                <id>stop-jar-process</id>
                <phase>post-integration-test</phase>
                <goals><goal>stop-all</goal></goals>
            </execution>
        </executions>
</plugin>

【讨论】:

【解决方案2】:

对我来说,它适用于 exec-maven-plugin 中的 exec 目标和 async 设置。

 <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.6.0</version>
    <executions>
      <execution>
        <id>Start your java process</id>
        <goals>
          <goal>exec</goal>
        </goals>
        <phase>pre-integration-test</phase>
      </execution>
    </executions>
    <configuration>
      <async>true</async>
      <executable>java</executable>
      <arguments>
        <argument>-classpath</argument>
        <classpath/><!-- classpath from the module dependencies-->
        <argument>your.MainClass</argument>
      </arguments>
      <environmentVariables>
        <somevariable>isSet</someVariable>
      </environmentVariables>
    </configuration>
</plugin>

maven 运行结束后,进程会自动终止。您可能还想查看 asyncDestroyOnShutdown 选项

【讨论】:

    【解决方案3】:

    我已经使用 maven-antrun-plugin 解决了这个问题。

    如果您的后台进程是 java 进程,您可以使用 java ant 目标并给它一个停止超时。如果您知道您的集成测试将在 N 秒后结束,请分叉并生成该进程并在超时 (N) 后停止该进程

            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.6</version>
                <executions>
                    <execution>
                        <id>start-my-Application</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <java jar="target/myapp-${project.version}.jar"
                                      spawn="true"
                                      fork="true"
                                      timeout="120">
                                    <sysproperty key="env" value="test" />
                                    <arg value="--xyz" /> <arg value="123" />
                                </java>
                            </target>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    

    【讨论】:

      【解决方案4】:

      如果这只是 Linux,我会将 PID 写入文件,然后稍后使用此 PID 终止进程。

      我的猜测是,您可以在 Windows 上实现类似的功能,但需要一些非标准工具。

      另一种方法是在新进程中打开一个套接字,并在这个套接字上监听一个 kill 命令。这适用于所有平台,但您需要修改 JAR。

      注意:如果您需要并行运行多个集成测试,这也会导致问题。

      【讨论】:

        【解决方案5】:

        最简单的方法是在你的外部 jar 中包含某种停止机制(与 tomcat 的停止端口相比)。

        这样您就不需要处理 PID 或任何东西。

        最简单、最节省资源的方法是在预定义(可覆盖)端口上打开服务器套接字。

        【讨论】:

          【解决方案6】:

          使用 call bash 杀死它

           <!--Kill the started process.-->
                    <target>
                      <exec executable="bash"
                            dir="${project.build.directory}"
                            spawn="false">
                        <arg value="-c"/>
                        <arg value="ps ax | grep -i '${project.artifactId}' | awk 'NR==1{print $1}' | xargs kill -SIGTERM"/>
                      </exec>
                    </target>
          

          【讨论】:

          • 为什么要将ps 的输出通过grepawk(当然可以使用grep 位)传送到kill 而不是使用pkill?跨度>
          • @OndrejK.maybe 因为我不知道您是否有更好的版本?
          • pkill 如前所述。
          猜你喜欢
          • 2014-01-12
          • 2013-03-20
          • 2015-06-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-21
          • 2020-01-02
          • 2018-01-10
          • 1970-01-01
          相关资源
          最近更新 更多