Selenium Grid 是用于设计帮助我们进行分布式测试的工具,其整个结构是由一个 hub 节点和若干个

代理节点组成。hub 用来管理各个代理节点的注册和状态信息,并且接受远程客户端代码的请求调用,然

后把请求的命令再转发给代理节点来执行。使用 Selenium Grid 远程执行测试的代码与直接调用

Selenium-Server 是一样的(只是环境启动的方式不一样,需要同时启动一个 hub 和至少一个 node):

> java -jar selenium-server-standalone-x.xx.x.jar -role hub

> java -jar selenium-server-standalone-x.xx.x.jar -role node

上面是启动一个 hub 和一个 node,hub 默认端口号为 4444,node 默认端口号为 5555;若是同一台机

器要启动多个 node 则要注意端口分配问题,可以这样来启动多个 node:

> java -jar selenium-server-standalone-x.xx.x.jar -role node -port 5555

> java -jar selenium-server-standalone-x.xx.x.jar -role node -port 5556

> java -jar selenium-server-standalone-x.xx.x.jar -role node -port 5557

调用 Selenium Grid 的基本结构图如下:

上面是使用 Selenium Grid 的一种普通方式,仅仅使用了其支持的分布式执行的功能,即当你同时需

要测试用例比较多时,可以平行的执行这些用例进而缩短测试总耗时;关于并发的技术需要借助编程语言

的多线程技术,我们会后面的章节深入学习 Python 的多线程技术。除此之外,Selenium Grid 还支持一种

更友好的功能,即可以根据你用例中启动测试的类型来相应的把用例转发给符合匹配要求的测试代理。例

如你的用例中指定了要在 Liunux 上 FireFox 的 17 版本进行测试,那么 Selenium Grid 会自动匹配注册信

息为 Linux、且安装了 FireFox17 的代理节点,如果匹配成功则转发测试请求,如果失败则拒绝请求。使

用 Selenium Grid 的远程兼容性测试的代码同上。其调用的基本结构图如下:

下面我们就来演示启动一个 hub 主节点和两个 node 分支节点。

node(5555)

Remote Control (legacy)

v:

v:

v:

WebDriver

v:

v:

v:

port:5555

servlets:[]

host:172.20.10.3

cleanUpCycle:5000

browserTimeout:0

hubHost:172.20.10.3

registerCycle:5000

capabilityMatcher:org.openqa.grid.internal.utils.DefaultCapabilityMatcher

newSessionWaitTimeout:-1

prioritizer:null

register:true

throwOnCapabilityNotPresent:true

nodePolling:5000

proxy:org.openqa.grid.selenium.proxy.DefaultRemoteProxy

maxSession:5

role:node

hubPort:4444

以上的信息为端口为 5555 的 node 信息。

Selenium Grid 应用

到目前为止,我们编写的脚本只能在固定的某一款浏览器上执行,因为在编写测试用例之前需要先指

定好浏览器的驱动(webdriver.Firefox、webdriver.Chrome),一旦确定了浏览器驱动是不能进行更改

的。我们希望写好的测试用例可以自由的切换成不同的浏览器来执行。

认识 Remote

WebDriver 提供了 Remote 可以发送指令到远程服务器控制浏览器。首先我们先来认识 Remote 的格式。

remote_ts.py

from selenium.webdriver import Remote

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

driver = Remote(command_executor='http://127.0.0.1:4444/wd/hub',

desired_capabilities=DesiredCapabilities.CHROME

)

……

driver.quit()

(注意:脚本的执行需要启动 Selenium Server。)

command_executor 为命令执行器,它用于指定脚本执行的主机及端口。

desired_capabilities 先不做解释,我们先看看它里面都包含了些什么?

Python Shell

>>> from selenium.webdriver.common.desired_capabilities import

DesiredCapabilities

>>> a=DesiredCapabilities.CHROME

>>> print a

{'platform': 'ANY', 'browserName': 'chrome', 'version': '', 'javascriptEnabled':

True}

Desired Capabilities 本质上是 key value 的对象,它告诉 Selenium Server 脚本执行的基本运行环

境:

'platform': ' 'ANY' 平台默认可以是任何(Windows,MAC,android)。

: 'browserName': 'chrome' 浏览器名字是 chrome。

: 'version': '' 浏览器的版本默认为空。

: 'javascriptEnabled': True javascript 启动状态为 True

认识了 Desired Capabilities 所包含的信息,在创建驱动(driver)时,可以这样来描述运行的环境:

remote_ts.py

from selenium.webdriver import Remote

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

driver = Remote(command_executor='http://127.0.0.1:4444/wd/hub',

desired_capabilities={'platform': 'ANY',

'browserName':'chrome',

'version': '',

'javascriptEnabled': True

})

……

driver.quit()

WebDriver API 提供了不同平台及浏览器的参数:

ANDROID = {'platform': 'ANDROID', 'browserName': 'android', 'version': '',

'javascriptEnabled': True}

CHROME = {'platform': 'ANY', 'browserName': 'chrome', 'version': '',

'javascriptEnabled': True}

FIREFOX = {'platform': 'ANY', 'browserName': 'firefox', 'version': '',

'javascriptEnabled': True}

HTMLUNIT = {'platform': 'ANY', 'browserName': 'htmlunit', 'version': ''}

HTMLUNITWITHJS = {'platform': 'ANY', 'browserName': 'htmlunit', 'version':

'firefox', 'javascriptEnabled': True}

INTERNETEXPLORER = {'platform': 'WINDOWS', 'browserName': 'internet

explorer', 'version': '', 'javascriptEnabled': True}

IPAD = {'platform': 'MAC', 'browserName': 'iPad', 'version': '',

'javascriptEnabled': True}

IPHONE = {'platform': 'MAC', 'browserName': 'iPhone', 'version': '',

'javascriptEnabled': True}

SAFARI = {'platform': 'ANY', 'browserName': 'safari', 'version': '',

'javascriptEnabled': True}

PHANTOMJS = {'platform': 'ANY', 'browserName': 'phantomjs', 'version': '',

'javascriptEnabled': True}

OPERA = {'platform': 'ANY', 'browserName': 'opera', 'version': '',

'javascriptEnabled': True}