自动化 Headless Selenium PHPUnit 测试
我之前谈到过在PHPUnit中运行Selenium测试,但我最近才开始正确地自动化操作。在脚本中启动和停止Selenium服务器相对容易,并且可以在一个简单的脚本中完成。我用于运行PHPUnit测试目录的原始脚本如下。我将在本文后面详细解释这一切是如何运作的。
# start selenium server java -jar selenium-server-standalone-2.24.1.jar -firefoxProfileTemplate SeleniumFirefoxProfile & # run unit tests phpunit Tests/ # stop selenium server wget -O - -q -t 1 http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer
这种方法的唯一问题是它会在运行时用Firefox窗口涂抹我的屏幕。当我进行了超过10次测试(发生得非常快)并在需要运行时接管了我的机器时,这成为一个大问题。所以我坐下来研究如何运行Selenium测试而不在屏幕上显示Firefox,或者所谓的“无头”模式。我需要做的是使用一个名为xvfb(X虚拟帧缓冲区)的服务器,它是一个x11服务器,在内存中执行所有图形操作,而不是将它们发送到显示器。x11,通常称为X,是Linux使用的图形用户界面引擎,用于显示所有窗口和其他图形。通过将Selenium服务器连接到xvfb服务器,所有Firefox窗口都将在那里打开而不显示在屏幕上。这也是在没有图形输出的服务器上完成工作的方式。我将假设您已经拥有在PHPUnit中运行Selenium测试所需的所有东西,但是要在Ubuntu系统上安装xvfb,请使用以下内容。
apt-getinstallxvfb
下一步是启动xvfb服务器。以下命令在端口99上创建一个大小为1024x768(深度为24)的虚拟屏幕,将帧内存保存到/tmp并且没有访问控制。-ac标志对于无头模式很重要,因为它意味着我们不必担心为此虚拟屏幕设置权限。
xvfb:99-screen01024x768x24-fbdir/tmp-ac
我在这里遇到的麻烦是,一旦开始,如果不使用ps和kill或按Ctrl+x就很难再次停止它。为此,我在互联网上浏览了一下,并整理了以下用于启动和停止xvfb服务器的脚本。我看过这个特定脚本的一些变体,但我无法确定是谁做的。
#!/bin/bash XVFB=/usr/bin/Xvfb XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /tmp -ac" PIDFILE=/tmp/xvfb.pid case "$1" in start) echo -n "Starting virtual X frame buffer: xvfb" start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS echo "." ;; stop) echo -n "Stopping virtual X frame buffer: xvfb" start-stop-daemon --stop --quiet --pidfile $PIDFILE echo "." ;; restart) $0 stop $0 start ;; *) echo "Usage: xvfb {start|stop|restart}" exit 1 esac exit 0
我将它保存为xvfb_control.sh,确保它是可执行的(通过命令chmod+xxvfb_control.sh),并使用以下命令运行xvfb服务器。
./xvfb_control.shstart
接下来要做的是确保Selenium服务器在运行时连接到这个xvfb服务器,而不是连接到主显示器(即我的显示器)。为此,您只需导出一个名为DISPLAY的系统属性,其中包含虚拟屏幕的位置。
exportDISPLAY=:99
在此之后,我们可以以几乎相同的方式启动Selenium服务器。此命令在后台启动服务器并将所有错误记录到文件/tmp/selenium_server.log。这是一种稍微更健壮的做事方式,因为它允许我看到Selenium引发的任何错误。
java-jarselenium-server-standalone-2.24.1.jar-firefoxProfileTemplateSeleniumFirefoxProfile>/tmp/selenium_server.log2>&1&
完成后,我们可以以正常方式运行PHPUnit测试,之后我们需要停止xfvb和Selenium服务器,因为它们不再需要了。要关闭xvfb服务器,我们只需运行之前的脚本,但这次发出停止命令。
./xvfb_control.shstop
Selenium可以简单地通过访问网页来停止,所以我们让wget默默地为我们做这件事。
wget-O--q-t1http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer
我将其整理到一个脚本文件中,以便同时运行一个目录中的所有Selenium单元测试。
#!/bin/bash ./xvfb_control.sh start export DISPLAY=:99 java -jar selenium-server-standalone-2.24.1.jar -firefoxProfileTemplate SeleniumFirefoxProfile > /tmp/selenium_server.log 2>&1 & echo "waiting for Selenium server to finish loading" sleep 3 echo "running tests" phpunit Tests/ echo "shutting down Selenium server" wget -O - -q -t 1 http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer ./xvfb_control.sh stop
这工作正常,但我发现一些测试因奇怪的错误而失败。这是测试失败之一的输出。
1) SeleniumHashbangcodeTest::testMyTestCase Invalid response while accessing the Selenium Server at 'http://localhost:4444/selenium-server/driver/': Timed out after 30000ms /Tests/SeleniumHashbangcodeTest.php:14 /Tests/SeleniumHashbangcodeTest.php:14 Caused by RuntimeException: Invalid response while accessing the Selenium Server at 'http://localhost:4444/selenium-server/driver/': Timed out after 30000ms /Tests/SeleniumHashbangcodeTest.php:14 /Tests/SeleniumHashbangcodeTest.php:14
我将其归结为我认为在PHPUnit测试开始运行之前Selenium服务器启动Firefox的时间过长。我注意到当我使用SeleniumFirefoxProfile正常启动Firefox时,它在加载之前对所有扩展进行了兼容性检查。这是毫无意义的,尤其是在无头模式下,因为如果找到它们,我将永远不会看到任何更新,但它似乎导致PHPUnit在测试运行之前超时。
为了阻止Firefox在每次加载时自动检查插件更新,您需要执行以下操作:
打开FireFox并选择正确的配置文件
转到关于:配置
右键单击任意位置并选择新建>布尔值以创建新值。
在出现的窗口中输入extensions.checkCompatibility并单击确定。
从可用选项列表中选择False,然后单击确定。
如果这也会导致问题,您可以选择对值extensions.checkUpdateSecurity执行相同的操作。随着extensions.checkCompatibility关闭了我的PHPUnitSelenium测试然后跑没有失败。