Selenium Grid2做分布式测试
介绍
网格允许你做的事情:
- 通过将测试分配到多台机器上进行扩展(并行执行)
- 从一个控制点集中管理多个环境,这使得非常容易的将测试运行在广阔的浏览器和操作系统组合上。
- 最小化网格的维护时间(允许实现自定义的钩子,以便利用虚拟基础设施)
快速指南
这个例子将告诉你如何开始Selenium2 Hub,并且注册一个WebDriver节点和一个RC节点。我们也将向您展示如何从java中调用网格。在这个例子中,hub和节点运行在同一台机器上,当然你也可以将selenium-server-standalone拷贝到多台机器上。注意:selenium-server-standalone包包括运行网格所需要的Hub,WebDriver,和legacy RC。Ant不再是必要的。你可以从http://selenium-release.storage.googleapis.com/index.html下载selenium-server-standalone-*.jar包。在http://docs.seleniumhq.org/download/的SeleniumStandalone Server节点,目前版本为3.4.0
第一步:启动hub
Hub是接受全部测试请求的集中点,并将测试请求发发送到正确的节点。
打开cmd并进入到selenium-server-standalone文件所在的目录,然后运行如下命令:java -jar selenium-server-standalone-<version>.jar -role hub
备注:在运行上述命令之前,需要先安装java的jre环境。可以从http://www.oracle.com/technetwork/java/index.html下载。安装完成后需要设置如下环境变量(windows):
变量名: JAVA_HOME
变量值: C:\ProgramFiles\Java\jdk1.7.0_45 \
变量名: PATH
变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
变量名: CALSS_PATH
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
Hub默认使用4444端口启动。如需要改变默认端口,在运行启动命令的时候可以增加-port参数来指定你需要使用的端口。你可以在浏览器里面打开http://localhost:4444/grid/console来查看hub的状态信息。
第二步:启动节点
不管是要使用WebDriver功能的网格还是RC功能的网格还是同事使用两者,都是使用selenium-server-standalone 的jar文件来启动节点。命令如下:
java -jarselenium-server-standalone-<version>.jar -role node -hub http://localhost:4444/grid/register
刚注册的节点:
备注:节点的默认端口是55555
为保持向后兼容, "wd"和"rc"角色依然是"node"角色的合法子集。但是这些角色限制了远程连接到对应的API的连接类型,然而"node" 同事允许RC和WebDriver的练级。
使用网格来运行测试
现在网格已经准备好了,我们需要从测试用例中访问网格,对于RC节点可以继续使用DefaultSelenium对象并传递hub的信息给它。
Selenium selenium = newDefaultSelenium(“localhost”, 4444, “*firefox”, “http://www.google.com”);
对于WebDrive节点,需要使用RemoteWebDriver和DesiredCapabilities对象来定义你希望使用的浏览器、版本和平台。
DesiredCapabilities capability= DesiredCapabilities.firefox();
将其传入RemoteWebDriver对象:
WebDriver driver = newRemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
Hub将测试分配给匹配的节点。
如果节点匹配所有的请求能力,为在网格上请求特定的能力,需要在传送给WebDriver之前指定这些请求的能力。
capability.setBrowserName();
capability.setPlatform();
capability.setVersion()
capability.setCapability(,);
例子:一个设置如下的节点:
-browser browserName=firefox,version=3.6,platform=LINUX
将匹配:
capability.setBrowserName(“firefox”);
capability.setPlatform(“LINUX”);
capability.setVersion(“3.6”);
也匹配
capability.setBrowserName(“firefox”);
capability.setVersion(“3.6”);
没有指定的能力将被忽略。如果你指定的能力在网格中不存在(如Firefox的版本为4.0但是没有Firefox的实例),那么就不会进行匹配且测试运行失败。
配置节点
配置节点的方式有两种;一种方式是通过命令行参数来指定,另外一种是通过json文件来指定。
通过命令行参数配置节点
启动节点是,默认可以并发使用11个浏览器;5个FireFox,5个Chrome,1个InternetExplorer。最大的并发测试数量是5。为改变浏览器设置,通过-browser开关指定参数(每一个开关代表一个节点)。如果你使用-browser参数,默认浏览器将被忽略并且只有你指定的命令行将被使用。
-browserbrowserName=firefox,version=3.6,maxInstances=5,platform=LINUX
这个设置是在linux机器上启动5个3.6版本的FirFox节点。
如果在远程机器上有多个需要使用的FireFox版本,可以通过路径来指定特定的版本:
-browserbrowserName=firefox,version=3.6,firefox_binary=/home/myhomedir/firefox36/firefox,maxInstances=3,platform=LINUX-browserbrowserName=firefox,version=4,firefox_binary=/home/myhomedir/firefox4/firefox,maxInstances=4,platform=LINUX
提示:如果你提供的参数有空格,使用双引号括起来:
-browser“browserName=firefox,version=3.6,firefox_binary=c:\Program Files\firefox,maxInstances=3, platform=WINDOWS”
可选参数
- -port 4444 (4444是默认端口号)
- -host <IP | hostname> 指定主机名或IP地址,通常这个是没有必要的且这个是自动确定的。对于外部网络配置(如v*n)指定主机可能是必须的。
- -timeout 30 (300秒是默认值)hub自动释放节点的超时毫秒数(没有收到任何请求)。在这个时间之后节点将被释放用于队列中的其他测试。这个清除客户端崩溃而不用手工介入。如果timeout的参数为0,将永远不会超时,hub永远不会释放节点。
注意:这个不是WebDriver的超时设置。(”wait for WebElement”类型命令)
- -maxSession 5 (5是默认值) 在节点上可以并发运行的浏览器数量。这个与支持的浏览器的maxInstance 不同(例如:一个支持Firefox 3.6, Firefox 4.0 and Internet Explorer 8的节点,maxSession=1将只会有一个浏览器运行,maxSession=2可以同时运行两个FireFox浏览器或者1个FireFox和1个Internet Explorer浏览器)。
- -browser < params > 如果 –browser参数没有设置,启动的节点将具有5 firefox, 1 chrome, and 1 internet explorer实例 (在Windows平台上). 这个参数可以在同一行设置多次,如:-browser: browserName={android, chrome, firefox, htmlunit, internet explorer, iphone, opera} version={browser version} firefox_binary={path to executable binary} chrome_binary={path to executable binary} maxInstances={maximum number of browsers of this type} platform={WINDOWS, LINUX, MAC}
- -registerCycle N = 在多少毫秒之后节点重新注册自己。这个允许重启hub而不用重启节点。
- 对于大容量的hub安装(超过50个节点),需要在java命令行增加jetty的线程数量-DPOOL_MAX=512 (or larger)
配置超时(2.21版本需要)
网格的超时通过webDriver.manage().timeouts()来处理,这个允许控制不同操作的超时。
为保持具有selenium-server网格的运行时完整性,有两个其他的超时值可以设置。
在hub上,使用-timeout选项设置30秒超时,这将确保在客户端崩溃后所有资源在30秒内被回收。通过-browserTimeout 60设置一个节点被浏览器挂起的最大时间。所有的节点都是用来自于hub设置的这两个值。一般建议不要在单独的节点上设置这些超时。
browserTimeout的设置应该是:
- 高于套接字锁定超时(45秒)
- 一般来说也要高于webDriver.manage().timeouts()设置的值, 因为这个是最后的防御机制。
用JSON配置节点
java -jar selenium-server-standalone.jar -rolenode -nodeConfig nodeconfig.json
3.x.x (>= beta4) 的配置可以参考 https://github.com/SeleniumHQ/selenium/blob/master/java/server/src/org/openqa/grid/common/defaults/DefaultNodeWebDriver.json
如下:
{ |
"capabilities": |
[ |
{ |
"browserName": "firefox", |
"maxInstances": 5, |
"seleniumProtocol": "WebDriver" |
}, |
{ |
"browserName": "chrome", |
"maxInstances": 5, |
"seleniumProtocol": "WebDriver" |
}, |
{ |
"browserName": "internet explorer", |
"maxInstances": 1, |
"seleniumProtocol": "WebDriver" |
} |
], |
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", |
"maxSession": 5, |
"port": 5555, |
"register": true, |
"registerCycle": 5000, |
"hub": "http://localhost:4444", |
"nodeStatusCheckTimeout": 5000, |
"nodePolling": 5000, |
"role": "node", |
"unregisterIfStillDownAfter": 60000, |
"downPollingLimit": 2, |
"debug": false, |
"servlets" : [], |
"withoutServlets": [], |
"custom": {} |
} |
2.x.x 版本的配置可以参考https://github.com/SeleniumHQ/selenium/blob/selenium-2.53.0/java/server/src/org/openqa/grid/common/defaults/DefaultNode.json
{ |
"capabilities": |
[ |
{ |
"browserName": "*firefox", |
"maxInstances": 5, |
"seleniumProtocol": "Selenium" |
}, |
{ |
"browserName": "*googlechrome", |
"maxInstances": 5, |
"seleniumProtocol": "Selenium" |
}, |
{ |
"browserName": "*iexplore", |
"maxInstances": 1, |
"seleniumProtocol": "Selenium" |
}, |
{ |
"browserName": "firefox", |
"maxInstances": 5, |
"seleniumProtocol": "WebDriver" |
}, |
{ |
"browserName": "chrome", |
"maxInstances": 5, |
"seleniumProtocol": "WebDriver" |
}, |
{ |
"browserName": "internet explorer", |
"maxInstances": 1, |
"seleniumProtocol": "WebDriver" |
} |
], |
"configuration": |
{ |
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", |
"maxSession": 5, |
"port": 5555, |
"host": ip, |
"register": true, |
"registerCycle": 5000, |
"hubPort": 4444, |
"hubHost": ip |
} |
} |
注意:在2.x.x里面的configuration{ ... }对象在3.x.x里面已经被取消。
用JSON配置hub
java -jar selenium-server-standalone.jar -rolehub -hubConfig hubconfig.json
hubconfig.json 配置内容请参考: https://github.com/SeleniumHQ/selenium/blob/master/java/server/src/org/openqa/grid/common/defaults/DefaultHub.json
Hub的诊断消息
当检测到异常使用模式时,hub会给出如下的消息:
Client requested session XYZthat was terminated due to REASON
原因 |
起因/修复 |
TIMEOUT |
会话超时,因为客户端在规定的超时时间里没有访问它。如果客户端已经被暂停执行就可能发生。 |
BROWSER_TIMEOUT |
节点浏览器超时,因其被挂起太长的时间。 (参数 browserTimeout) |
ORPHAN |
在队列中等待的客户端放弃了,因其被赋予了新的会话。 |
CLIENT_STOPPED_SESSION |
客户端调用stop/quit终止了会话。为什么又在使用呢???? |
CLIENT_GONE |
客户端进程已经死机或者对请求没有回应,不稳定的网络也可能导致这个问题。 |
FORWARDING_TO_NODE_FAILED |
Hub不能转发给节点。内存不足、节点稳定性问题或网络问题 |
CREATIONFAILED |
节点创建浏览器失败。主要是节点环境或配置问题。尝试直接使用节点来跟踪问题。 |
PROXY_REREGISTRATION |
会话被丢弃,因为节点重新注册到了网格。 |
使用网格要点:
如果你的测试是并发运行的,请确保每一个线程有独占的webdriver资源。在线程开始运行的时候每个线程分配一个浏览器然后在线程结束的时候释放所有的浏览器,这并不是一个好的注意。(因为如果一个测试用例花费了太多的时间,可能导致剩余的测试超时,因为都在等待这个慢的测试。这个会令人感到迷惑)