Selenium Grid 入门
快速入门
- 前提条件
- 安装 Java 11 或更高版本
- 安装浏览器
- 浏览器驱动
- 如果添加
--selenium-manager true
,Selenium Manager 将自动配置驱动程序。 - 已安装并在
PATH
中
- 如果添加
- 从最新版本下载 Selenium Server jar 文件
- 启动 Grid
java -jar selenium-server-<version>.jar standalone
- 将您的 WebDriver 测试指向 http://localhost:4444
- (可选)通过在浏览器中打开 http://localhost:4444 来检查正在运行的测试和可用功能
*想知道如何将测试指向 http://localhost:4444 吗?查看 RemoteWebDriver
部分。
要了解有关不同配置选项的更多信息,请阅读以下各节。
Grid 角色
Grid 由六个不同的组件组成,这使您可以选择以不同的方式部署它。
根据您的需要,您可以单独启动每个组件(分布式),将它们分组到中心和节点中,或者全部在一台机器上(独立模式)。
独立模式
独立模式 将所有 Grid 组件 无缝地组合到一个中。在 独立模式 下运行 Grid,您只需一个命令即可在单个进程中获得功能齐全的 Grid。独立模式 只能在单个机器上运行。
独立模式 也是启动 Selenium Grid 的最简单模式。默认情况下,服务器将在 http://localhost:4444 上侦听 RemoteWebDriver
请求。默认情况下,服务器将检测它可以从系统 PATH
中使用的可用驱动程序。
java -jar selenium-server-<version>.jar standalone
成功在独立模式下启动 Grid 后,将您的 WebDriver 测试指向 http://localhost:4444。
独立模式 的常见用例是
- 在本地使用
RemoteWebDriver
开发或调试测试 - 在推送代码之前运行快速测试套件
- 在 CI/CD 工具(GitHub Actions、Jenkins 等)中拥有易于设置的 Grid
中心和节点模式
中心和节点模式 是最常用的角色,因为它允许
- 在单个 Grid 中组合不同的机器
- 例如,具有不同操作系统和/或浏览器版本的机器
- 拥有一个在不同环境中运行 WebDriver 测试的单一入口点
- 在不关闭 Grid 的情况下向上或向下扩展容量
中心
中心由以下组件组成:路由器、分配器、会话映射、新会话队列和事件总线。
java -jar selenium-server-<version>.jar hub
默认情况下,服务器将在 http://localhost:4444 上侦听 RemoteWebDriver
请求。
节点
在启动时,节点 将检测它可以从系统 PATH
中使用的可用驱动程序。
以下命令假设 节点 与运行 中心 的机器在同一台机器上运行。
java -jar selenium-server-<version>.jar node
同一台机器上的多个节点
节点 1
java -jar selenium-server-<version>.jar node --port 5555
节点 2
java -jar selenium-server-<version>.jar node --port 6666
不同机器上的节点和中心
中心 和 节点 通过 HTTP 和 事件总线(事件总线 位于 中心 内)相互通信。节点 通过 事件总线 向 中心 发送消息以启动注册过程。当 中心 收到消息时,会通过 HTTP 连接到 节点 以确认其存在。
为了成功将 节点 注册到 中心,重要的是在 中心 机器上公开 事件总线 端口(默认为 4442 和 4443)。这也适用于 节点 端口。这样,中心 和 节点 才能进行通信。
如果 中心 使用默认端口,则可以使用 --hub
标志注册 节点
java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444
当 中心 不使用默认端口时,需要 --publish-events
和 --subscribe-events
标志。
例如,如果 中心 使用端口 8886
、8887
和 8888
java -jar selenium-server-<version>.jar hub --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887 --port 8888
节点 需要使用这些端口才能成功注册
java -jar selenium-server-<version>.jar node --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887
分布式模式
当使用分布式 Grid 时,每个组件都是单独启动的,理想情况下是在不同的机器上。
- 事件总线:启用不同 Grid 组件之间的内部通信。
默认端口为:4442
、4443
和 5557
。
java -jar selenium-server-<version>.jar event-bus --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5557
- 新会话队列:将新的会话请求添加到队列中,分配器将查询该队列
默认端口为 5559
。
java -jar selenium-server-<version>.jar sessionqueue --port 5559
- 会话映射:将会话 ID 映射到运行会话的 节点
默认的 会话映射 端口为 5556
。会话映射 与 事件总线 交互。
java -jar selenium-server-<version>.jar sessions --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5556
- 分配器:查询 新会话队列 中新的会话请求,并在功能匹配时将其分配给 节点。节点 以它们在 中心/节点 Grid 中注册到 中心 的方式注册到 分配器。
默认的 分配器 端口为 5553
。分配器 与 新会话队列、会话映射、事件总线 和 节点 交互。
java -jar selenium-server-<version>.jar distributor --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --sessions http://<sessions-ip>:5556 --sessionqueue http://<new-session-queue-ip>:5559 --port 5553 --bind-bus false
- 路由器:将新的会话请求重定向到队列,并将正在运行的会话请求重定向到运行该会话的 节点。
默认的 路由器 端口为 4444
。路由器 与 新会话队列、会话映射 和 分配器 交互。
java -jar selenium-server-<version>.jar router --sessions http://<sessions-ip>:5556 --distributor http://<distributor-ip>:5553 --sessionqueue http://<new-session-queue-ip>:5559 --port 4444
- 节点
默认的 节点 端口为 5555
。
java -jar selenium-server-<version>.jar node --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443
测试中的元数据
将元数据添加到您的测试中,并通过 GraphQL 使用它,或通过 Selenium Grid UI 可视化其中的一部分(如 se:name
)。
可以通过在功能前加上 se:
来添加元数据。这是一个快速 Java 示例,展示了这一点。
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "100");
chromeOptions.setCapability("platformName", "Windows");
// Showing a test name instead of the session id in the Grid UI
chromeOptions.setCapability("se:name", "My simple test");
// Other type of metadata can be seen in the Grid UI by clicking on the
// session info or via GraphQL
chromeOptions.setCapability("se:sampleMetadata", "Sample metadata value");
WebDriver driver = new RemoteWebDriver(new URL("http://gridUrl:4444"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
查询 Selenium Grid
启动 Grid 后,主要有两种方法可以通过 Grid UI 或通过 API 调用来查询其状态。
可以通过打开您喜欢的浏览器并访问 http://localhost:4444 来访问 Grid UI。
可以通过 http://localhost:4444/status 端点或使用 GraphQL 进行 API 调用
为简单起见,此页面中显示的所有命令示例都假设组件在本地运行。有关更详细的示例和用法,请参阅配置组件部分。
使用 Java 11 HTTP 客户端
默认情况下,Grid 将使用 AsyncHttpClient。AsyncHttpClient 是一个基于 Netty 构建的开源库。它允许异步执行 HTTP 请求和响应。此外,它还提供 WebSocket 支持。因此,它非常适合。
但是,AsyncHttpClient 自 2021 年 6 月以来一直没有得到积极维护。这与 Java 11+ 提供内置 HTTP 和 WebSocket 客户端的事实相吻合。目前,Selenium 计划将支持的最低版本升级到 Java 11。但是,这是一项相当大的工作。将其与主要版本保持一致并附带公告对于确保用户体验完好至关重要。
要使用 Java 11 客户端,您需要下载 selenium-http-jdk-client
jar 文件,并使用 --ext
标志使其在 Grid jar 的类路径中可用。
可以直接从 repo1.maven.org 下载 jar 文件,然后按以下方式启动 Grid
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext selenium-http-jdk-client-<version>.jar standalone
下载 selenium-http-jdk-client
jar 文件的另一种方法是使用 Coursier。
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext $(coursier fetch -p org.seleniumhq.selenium:selenium-http-jdk-client:<version>) standalone
如果您使用 Hub/Node(集线器/节点)模式或分布式模式,则需要在每个组件上设置 -Dwebdriver.http.factory=jdk-http-client
和 --ext
标志。
Grid 规模
选择 Grid 角色取决于需要支持的操作系统和浏览器、需要执行的并行会话数量、可用机器的数量以及这些机器的性能(CPU、RAM)。
并发创建会话取决于 **Distributor(分配器)**可用的处理器。例如,如果一台机器有 4 个 CPU,则 **Distributor(分配器)**最多只能同时创建 4 个会话。
默认情况下,一个 **Node(节点)** 支持的最大并发会话数受可用 CPU 数量的限制。例如,如果 **Node(节点)** 机器有 8 个 CPU,则它可以运行最多 8 个并发浏览器会话(Safari 除外,它始终为 1 个)。此外,预计每个浏览器会话应使用大约 1GB 的 RAM。
通常,建议 **Nodes(节点)** 尽可能小。与其使用一台具有 32 个 CPU 和 32GB RAM 的机器来运行 32 个并发浏览器会话,不如拥有 32 个小型 **Nodes(节点)** 以更好地隔离进程。这样,如果某个 **Node(节点)** 发生故障,它将以隔离的方式进行。Docker 是实现这种方法的一个很好的工具。
请注意,默认值(每个浏览器 1 个 CPU/1GB RAM)是建议值,可能不适用于您的环境。建议将它们作为参考,但持续测量性能将有助于确定您的环境的理想值。
Grid 的大小与支持的并发会话数量和 **Nodes(节点)** 的数量相关,没有“一刀切”的方法。下面提到的尺寸是粗略的估计,可能因不同的环境而异。例如,当 **Hub(集线器)** 有足够的资源时,具有 120 个 **Nodes(节点)** 的 **Hub/Node(集线器/节点)** 可能会运行良好。以下值并非一成不变,欢迎反馈!
小型
Standalone(独立) 或具有 5 个或更少 **Nodes(节点)** 的 Hub/Node(集线器/节点)。
中型
Hub/Node(集线器/节点) 在 6 到 60 个 **Nodes(节点)** 之间。
大型
Hub/Node(集线器/节点) 在 60 到 100 个 **Nodes(节点)** 之间。 Distributed(分布式) 具有超过 100 个 **Nodes(节点)**。
警告
必须使用适当的防火墙权限保护 Selenium Grid 免受外部访问。
未能保护您的 Grid 可能会导致以下一项或多项情况发生
- 您向您的 Grid 基础设施提供开放访问权限
- 您允许第三方访问内部 Web 应用程序和文件
- 您允许第三方运行自定义二进制文件
请参阅 Detectify 上的这篇博客文章,其中很好地概述了如何滥用公开的 Grid:不要让您的 Grid 完全开放