众所周知,使用 WebDriver 启动浏览器进行 Web UI 自动化测试的执行速度是很慢的,于是使用 Selenium Grid 进行并发测试是减少测试执行时间的一个非常好的手段。
认识 Grid
Grid 允许在远程计算机上执行WebDriver脚本,它通过将客户端命令发送到远程浏览器的实例,提供了一种在多台计算机上并行运行测试的简便方法。
Grid允许我们在多台计算机上并行运行测试, 并集中管理不同的浏览器版本和浏览器配置 (而不是在每个独立的测试中)。
Grid目的和主要功能:
- 为所有的测试提供统一的入口
- 管理和控制运行着浏览器的节点/环境
- 扩展
- 并行测试
- 跨平台(操作系统)测试
- 负载测试
一般我们在如下两种情况下使用Grid:
- 在多种浏览器,多种版本的浏览器,不同操作系统里的浏览器里执行你的测试
- 缩短完成测试的时间
PS:由于 Grid 3 Selenium已不再提供支持,本文中,我们将介绍Grid 4。
Grid 组件
如上图所示,Grid 主要由以下组件构成:
Router:
路由器(Router)负责将请求转发到正确的组件。它是Grid的入口,所有外部请求都将借此被网格接收。
路由器的行为取决于请求:如果是新的会话请求, 则路由器会将其转发到分发服务器(Distributor) (将在其中处理并创建新的会话);如果请求属于已存在的会话,则路由器会将会话ID发送到会话集合, 会话集合将返回会话正在运行的节点(Node),此后, 路由器会将请求转发到节点。
路由器旨在通过将请求发送到能够更好地处理请求的组件, 来平衡网格中的负载, 从而避免过程中任何组件无谓地过载。
Distributor:
分发器(Distributor)知道所有节点及其功能,它的主要作用是接收新的会话请求并找到可以在其中创建会话的适当节点。创建会话后, 分发器在会话集合中存储会话ID与正在执行会话的节点之间的关系。
Node:
一个节点(Node)可以在Grid中出现多次,每个节点负责管理其运行机器的可用浏览器的插槽。
节点通过事件总线(Event Bus)将其自身注册到分发服务器, 并且将其配置作为注册消息的组成部分一起发送。
默认情况下, 节点会自动注册运行它的计算机路径上所有可用的浏览器驱动程序,它还为基于Chromium的浏览器和Firefox的每个可用的CPU都创建插槽。对于Safari和Internet Explorer, 则仅创建一个插槽。通过特定的配置, 它可以在Docker容器中运行会话。
节点仅执行接收到的命令, 它不进行评估、做出判断或控制任何事情。运行节点的计算机不需要与其他组件具有相同的操作系统。例如, Windows节点可以具有将Internet Explorer作为浏览器选项的功能, 而在Linux或Mac上则无法实现。
Session Map:
会话集合(Session Map)是一种数据存储的形式, 用于保存会话ID和会话正在运行的节点的信息。它在将请求转发到节点的过程中为路由器提供支持,路由器将向会话集合询问与会话ID关联的节点。当以完全分布式模式启动Grid时, Session Map是应该启动的第一个组件。
New Session Queuer,New Session Queue :
新会话队列者(New Session Queuer)是唯一可以与新会话队列(New Session Queue)通信的组件。它处理所有的队列操作,例如,像“add”去操作队列。它提供配置参数设置请求超时和请求重试的间隔。
新会话队列者通过路由接收新会话请求并将其添加到队列中,它会一直等待直到它收到请求的响应。如果请求超时,请求立刻被拒绝并且不会添加到队列中。
如果请求的功能在任何已注册的节点都不存在,那么请求立刻被拒绝,客户端收到响应。
如果请求的功能与任何节点的插槽匹配,分发器将尝试获取可用的插槽,如果所有插槽都很忙,分发器将要求会话队列者将请求添加到队列前面。在请求重试间隔后,分发器再次接受请求。不停的尝试重试,直到请求成功或超时。如果请求在重试可添加到队列前超时,则其被拒绝。
在获得可用的插槽和创建会话之后,分发器通过事件总线(Event Bus)将新会话响应传递给新会话队列者。新会话队列者在接收到事件时响应客户端。
Event Bus:
事件总线(Event Bus)作为一种通讯的路径, 服务于节点、分发服务器和会话集合之间。Grid通过消息进行大部分内部通信, 从而避免了昂贵的HTTP调用。
Roles in Grid:
在Gird 3中, 组件是集线器(hub)和节点(Node), 可以通过以独立模式启动网格来一起运行它们。
Grid 4中提供了相同的概念, 可以通过对上述某些组件进行分组来运行集线器, 也可以在独立模式下一起运行所有组件.
集线器(hub)是以下组件的结合:
- 路由器(Router)
- 分发器(Distributor)
- 会话集合(Session Map)
- 事件总线(Event Bus)
它启用传统集线器(hub)和节点(node or nodes)的设置。
Standalone
如前所述, 单机模式(Standalone)是所有组件的结合, 并且在用户看来, 它们作为一个组件执行,这包括集线器的部分组件, 再加上一个节点。在独立模式下启动后, 可以使用一个功能齐全的Grid。
Grid4
运行模式
在Grid 4 中有四种运行模式:
- 单机(Standalone)
- Hub and Node
- 分发器(Distributed)
- Docker
单机模式(Standalone):
新的Selenium-Server Jar 包含运行Grid所需的全部内容,这也是最简单的Grid运行模式。
默认情况下, Selenium-Server将监听http://localhost:4444, 这是测试代码中应该指向的RemoteWebDriver测试URL,Selenium-Server将从系统路径中检测可用的驱动程序。
启动方式:
java -jar selenium-server-4.0.0-alpha-7.jar standalone |
---|
测试代码:
from selenium import webdriverfrom selenium.webdriver import DesiredCapabilities driver = webdriver.Remote(command_executor='http://127.0.0.1:4444', desired_capabilities=DesiredCapabilities.CHROME.copy() )“””测试执行代码””” |
---|
Hub and Node 模式:
启动方式:
# 启动hubjava -jar selenium-server-4.0.0-alpha-7.jar hub # 启动nodejava -jar selenium-server-4.0.0-alpha-7.jar node |
---|
测试代码:
from selenium import webdriverfrom selenium.webdriver import DesiredCapabilities driverHub = webdriver.Remote(command_executor='http://127.0.0.1:4444', desired_capabilities=DesiredCapabilities.CHROME.copy() )driverNode = webdriver.Remote(command_executor='http://127.0.0.1:5555', desired_capabilities=DesiredCapabilities.CHROME.copy() )“””测试执行代码””” |
---|
分布式模式(Distributed):
第1步: 首先, 启动事件总线,
它在后续步骤中充当到其他网格组件的通信路径:
java -jar selenium-server-4.0.0-alpha-7.jar event-bus |
---|
第2步: 启动会话映射, 其负责将会话ID到会话运行节点的映射:
java -jar selenium-server-4.0.0-alpha-7.jar sessions |
---|
第3步: 启动新的会话队列, 它将新的会话请求添加到本地队列中. 分发服务器从队列中接收请求:
java -jar selenium-server-4.0.0-alpha-7.jar sessionqueuer |
---|
第4步: 启动分发器.,所有节点都附加到发进程上, 作为其组成的一部分, 负责在会话的创建时分配节点:
java -jar selenium-server-4.0.0-alpha-7.jar distributor --sessions http://localhost:5556 --sessionqueuer http://localhost:5559 --bind-bus false |
---|
第5步:下一步是启动路由器, 你将暴露给网络一个地址.
java -jar selenium-server-4.0.0-alpha-7.jar router --sessions http://localhost:5556 --distributor http://localhost:5553 --sessionqueuer http://localhost:5559 |
---|
第6步: 最终,添加节点.
java -jar selenium-server-4.0.0-alpha-7.jar node |
---|
Docker 启动 Grid:
通过以下命令启动一个节点:
java -jar selenium-server-4.0.0-alpha-7.jar node -D selenium/standalone-firefox:latest '{"browserName": "firefox"}' |
---|
启动Selenium服务器并将其委托给docker以创建新实例:
java -jar selenium-server-4.0.0-alpha-7.jar standalone -D selenium/standalone-firefox:latest '{"browserName": "firefox"}' --detect-drivers false |
---|