如何在Xvfb上启动mvn测试阶段?

5

我使用fest创建了一些单元测试,现在我需要在无头系统上使用maven运行我的测试。我想使用Xvfb运行测试,但我需要帮助配置maven在测试之前启动Xvfb,并在所有测试完成后停止它。

3个回答

3
使用exec-maven-plugin插件:
您需要定义两个执行步骤,一个用于启动服务器,另一个用于停止它。您需要将这些执行配置与适当的maven阶段相关联--在测试阶段之前启动Xvfb,在测试阶段之后停止Xvfb。
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>

            <executions>
                <execution>
                    <id>exec-at-test-compile</id>
                    <phase>test-compile</phase> <!-- runs right before 'test' -->
                    <goals>
                        <goal>exec</goal>
                    </goals>
                    <configuration>
                        <executable>/home/anew/bin/manage-xvfb.sh</executable>
                        <arguments>
                            <argument>start</argument>
                        </arguments>
                    </configuration>
                </execution>
                <execution>
                    <id>exec-at-prepare-package</id>
                    <phase>prepare-package</phase> <!-- runs right after 'test' -->
                    <goals>
                        <goal>exec</goal>
                    </goals>
                    <configuration>
                        <executable>/home/anew/bin/manage-xvfb.sh</executable>
                        <arguments>
                            <argument>stop</argument>
                        </arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>

这是 manage-xvfb.sh 脚本的内容:
#!/bin/bash

XVFB_CMD="sudo /usr/bin/Xvfb :15 -ac -screen 0 1024x768x8"

function stop_xvfb {
  XVFB_PID=`ps ax | pgrep "Xvfb"`
  if [ "${XVFB_PID}" != "" ]; then
    sudo kill ${XVFB_PID}
  fi
}

if [ "${1}" == "start" ]; then
  stop_xvfb
  ${XVFB_CMD} &
elif [ "${1}" == "stop" ]; then
  stop_xvfb
fi 

请注意,您需要在sudoers文件中设置NOPASSWD

我这里有两个问题:第一,执行Xvfb maven等待进程终止(我们需要一种在后台运行的方法,可能是运行调用Xvfb :1 &的shell脚本);第二,如果某些测试失败,则不会执行prepare-package阶段,因此Xvfb将继续运行。 - Alepac
创建一个shell脚本,它a)检查是否仍在运行先前的测试运行中的Xvfb——如果是,则杀死它。您需要执行类似于kill \ps axuf | pgrep Xvfb`的操作来杀死它。并且b)如果没有运行,则使用行末的&运算符启动Xvfb,以便您的shell脚本可以退出但会异步地保留Xvfb运行,如下所示:/usr/X11R6/bin/Xvfb :15 -ac -screen 0 1024x768x8 &`。 - Anew
我已经更新了我的示例,以便向您展示我的意思。希望它有所帮助。 - Anew

1
实际上,我使用了这个插件配置:
<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>start-xvfb</id>
            <phase>process-test-classes</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <tasks>
                    <echo message="Starting xvfb ..." />
                    <exec executable="Xvfb" spawn="true">
                        <arg value=":1" />
                    </exec>
                </tasks>
            </configuration>
        </execution>
        <execution>
            <id>shutdown-xvfb</id>
            <phase>test</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <tasks>
                    <echo message="Ending xvfb ..." />
                    <exec executable="killall">
                            <arg value="Xvfb" />
                    </exec>
                </tasks>
            </configuration>
        </execution>
    </executions>
</plugin>

好处是您可以获得一个后台进程(使用 spawn = "true"),并且您可以在不编写任何脚本的情况下杀死 Xvfb 进程(使用 killall)。此外,在我的 Ubuntu 发行版中,我不需要在 sudoers 文件中设置任何特殊设置才能让它工作。
关闭 Xvfb 执行在测试阶段结束时执行,但(问题在于)如果测试失败,则不会执行。如果您想重新启动另一个测试,这不是问题(旧的 Xvfb 仍在运行,新的无法运行,但这不是问题),但问题在于资源仍然被 Xvfb 占用。解决方法是将 testFailureIgnore = "true" 添加到 maven-surefire-plugin 的配置中,但这样我就不能轻松地看到是否有测试失败。

那也可以。好奇的是,为什么你不在启动start-xvfb时,在Xvfb之前添加<exec executable="killall"><arg value="Xvfb" /></exec>呢?或者你主要担心因为其他(童子军营地)原因而让Xvfb继续运行?另外,使用类似Jenkins这样的CI环境,触发其他构建以处理失败是微不足道的(例如,“停止Xvfb”构建)。 - Anew
@Anew 我之所以在启动前不添加killall,是因为在我的环境中没有任何错误(如果已经有另一个实例,则第二个实例根本不会启动),但我希望在结束时停止它,以始终保持清洁的环境(我甚至将此PC用于其他任务)。感谢您使用Jenkins / Hudson或其他CI环境的建议,我已经编写了设置这样的东西,一旦我有时间学习如何做到这一点。 - Alepac

0

这项工作可以通过 selenium-maven-plugin 轻松完成:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>selenium-maven-plugin</artifactId>

  <executions>
    <execution>
      <id>setup-xvfb</id>
      <phase>pre-integration-test</phase>
      <goals>
        <goal>xvfb</goal>
      </goals>
    </execution>
  </executions>
</plugin>

很遗憾,这个插件似乎已经不再维护了。它曾是mojohaus项目的一部分,该项目最近从codehaus.org迁移到了github.com。目前似乎还没有人将selenium-maven-plugin移植到github上,因此源代码和文档目前在mojohaus的github页面上无法获取。

然而,JAR包可以在Maven Central上获取,插件仍然可以使用。如果您需要查找更多配置参数,可以在github上找到源代码和站点的分支here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接