Selenium Grid

Selenium Grid | 菜鸟教程,先学习前面这篇文章里面的基础,再看我下面写的文章会更加容易理解。

一、Selenium Grid 是什么?

1. 核心概念

Selenium Grid 是一个代理服务器,它允许你将测试命令路由到多个远程浏览器实例。它的主要目的是:

  • 并行执行:同时在多个浏览器和操作系统上运行测试

  • 跨浏览器测试:在不同的浏览器类型和版本上测试应用

  • 跨平台测试:在不同的操作系统上测试应用

  • 负载分发:将测试负载分发到多台机器

2. 架构组件

Selenium Grid 4 采用新的架构,包含两个主要组件:

  1. Hub:中心节点,接收测试请求并分发到合适的节点

  2. Node:工作节点,执行实际的测试命令

python 复制代码
[你的测试脚本] → [Hub] → [Node 1 (Chrome on Windows)]
                   │
                   → [Node 2 (Firefox on macOS)]
                   │
                   → [Node 3 (Safari on iOS)]

二、Selenium Grid 4 的部署方式

1. 独立模式 (Standalone) - 最简单的方式

独立模式将 Hub 和 Node 合并到一个进程中,适合快速开始:

bash 复制代码
# 下载最新版本的Selenium Server
# 从 https://www.selenium.dev/downloads/ 下载selenium-server-x.x.x.jar

# 启动Standalone模式
java -jar selenium-server-4.15.0.jar standalone

# 指定端口
java -jar selenium-server-4.15.0.jar standalone --port 4444

2. 中心与节点模式 (Hub and Nodes) - 经典分布式模式

启动 Hub:
bash 复制代码
# 启动Hub(默认端口4444)
java -jar selenium-server-4.15.0.jar hub

# 自定义配置启动Hub
java -jar selenium-server-4.15.0.jar hub \
  --port 4444 \
  --selenium-manager true \
  --cors true
启动 Node:
bash 复制代码
# 注册Node到Hub
java -jar selenium-server-4.15.0.jar node \
  --hub http://localhost:4444

# 指定Node配置
java -jar selenium-server-4.15.0.jar node \
  --hub http://localhost:4444 \
  --port 5555 \
  --max-sessions 5 \
  --browser browserName=chrome,maxInstances=5

3. 分布式模式 - 高级部署

对于大规模部署,可以使用完全分布式的模式:

bash 复制代码
# 启动Event Bus(事件总线)
java -jar selenium-server-4.15.0.jar event-bus

# 启动Session Map(会话映射)
java -jar selenium-server-4.15.0.jar sessions

# 启动Session Queue(会话队列)
java -jar selenium-server-4.15.0.jar sessionqueue

# 启动Distributor(分发器)
java -jar selenium-server-4.15.0.jar distributor

# 启动Router(路由器)
java -jar selenium-server-4.15.0.jar router

# 启动Node(节点)
java -jar selenium-server-4.15.0.jar node

三、Docker 部署 - 推荐的生产环境方式

使用 Docker 可以简化 Grid 的部署和管理:

1. 快速启动 Standalone

bash 复制代码
docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-chrome:4.15.0

2. 启动完整的 Hub + Node 集群

bash 复制代码
# 启动Hub
docker run -d -p 4442-4444:4442-4444 --name selenium-hub selenium/hub:4.15.0

# 启动Chrome节点
docker run -d --name selenium-chrome-node \
  -p 5900:5900 \
  -e SE_EVENT_BUS_HOST=selenium-hub \
  -e SE_EVENT_BUS_PUBLISH_PORT=4442 \
  -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \
  -v /dev/shm:/dev/shm \
  selenium/node-chrome:4.15.0

# 启动Firefox节点
docker run -d --name selenium-firefox-node \
  -p 5901:5900 \
  -e SE_EVENT_BUS_HOST=selenium-hub \
  -e SE_EVENT_BUS_PUBLISH_PORT=4442 \
  -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \
  -v /dev/shm:/dev/shm \
  selenium/node-firefox:4.15.0

3. 使用 Docker Compose(推荐)

创建 docker-compose.yml 文件:

bash 复制代码
version: '3.8'
services:
  hub:
    image: selenium/hub:4.15.0
    container_name: selenium-hub
    ports:
      - "4442:4442"
      - "4443:4443"
      - "4444:4444"
  
  chrome:
    image: selenium/node-chrome:4.15.0
    container_name: selenium-chrome
    shm_size: 2gb
    environment:
      - SE_EVENT_BUS_HOST=hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
    depends_on:
      - hub
  
  firefox:
    image: selenium/node-firefox:4.15.0
    container_name: selenium-firefox
    shm_size: 2gb
    environment:
      - SE_EVENT_BUS_HOST=hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
    depends_on:
      - hub

然后运行:

bash 复制代码
docker-compose up -d

四、编写兼容 Grid 的测试脚本

1. 基本 Grid 测试脚本

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.remote.webdriver import WebDriver

def test_with_grid():
    # Grid Hub 的地址
    grid_url = "http://localhost:4444"
    
    # 创建浏览器选项
    chrome_options = Options()
    chrome_options.set_capability("browserName", "chrome")
    chrome_options.set_capability("browserVersion", "latest")
    chrome_options.set_capability("platformName", "LINUX")
    
    # 创建远程WebDriver实例
    driver = webdriver.Remote(
        command_executor=grid_url,
        options=chrome_options
    )
    
    try:
        # 执行测试
        driver.get("https://www.example.com")
        print(f"页面标题: {driver.title}")
        
        # 进行一些操作
        search_box = driver.find_element(By.NAME, "q")
        search_box.send_keys("Selenium Grid")
        search_box.submit()
        
        # 验证结果
        assert "Selenium Grid" in driver.title
        
    finally:
        # 关闭浏览器
        driver.quit()

if __name__ == "__main__":
    test_with_grid()

2. 多浏览器并行测试

python 复制代码
import concurrent.futures
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.firefox.options import Options as FirefoxOptions

def run_test(browser_name, browser_version="latest"):
    grid_url = "http://localhost:4444"
    
    if browser_name.lower() == "chrome":
        options = ChromeOptions()
    elif browser_name.lower() == "firefox":
        options = FirefoxOptions()
    else:
        raise ValueError(f"不支持的浏览器: {browser_name}")
    
    options.set_capability("browserName", browser_name)
    options.set_capability("browserVersion", browser_version)
    options.set_capability("platformName", "LINUX")
    
    driver = webdriver.Remote(
        command_executor=grid_url,
        options=options
    )
    
    try:
        driver.get("https://www.example.com")
        print(f"{browser_name}: 页面标题 - {driver.title}")
        
        # 执行一些测试逻辑
        # ...
        
        return f"{browser_name} 测试通过"
        
    finally:
        driver.quit()

# 并行运行多个浏览器测试
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    browsers = ["chrome", "firefox", "chrome"]
    results = list(executor.map(run_test, browsers))
    
    for result in results:
        print(result)

3. 高级配置和自定义能力

python 复制代码
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def test_with_advanced_capabilities():
    grid_url = "http://localhost:4444"
    
    chrome_options = Options()
    
    # 设置基本能力
    chrome_options.set_capability("browserName", "chrome")
    chrome_options.set_capability("browserVersion", "118")
    chrome_options.set_capability("platformName", "Windows 10")
    
    # 设置高级能力
    chrome_options.set_capability("selenoid:options", {
        "enableVNC": True,        # 启用VNC远程查看
        "enableVideo": False,     # 禁用视频录制
        "enableLog": True,        # 启用日志记录
        "screenResolution": "1920x1080x24",
        "env": ["LANG=zh_CN.UTF-8", "LANGUAGE=zh:en", "LC_ALL=zh_CN.UTF-8"],
        "timeZone": "Asia/Shanghai"
    })
    
    # 添加自定义标签,用于筛选节点
    chrome_options.set_capability("custom:label", "smoke-test")
    
    driver = webdriver.Remote(
        command_executor=grid_url,
        options=chrome_options
    )
    
    try:
        driver.get("https://www.example.com")
        # 测试逻辑...
        
    finally:
        driver.quit()

五、Grid 管理和监控

1. Grid 控制台

访问 http://localhost:4444 查看 Grid 控制台,可以:

  • 查看所有注册的节点

  • 监控当前会话

  • 查看节点配置和能力

2. 使用 Grid API

Grid 提供了 REST API 用于管理和监控:

python 复制代码
import requests
import json

class GridManager:
    def __init__(self, grid_url="http://localhost:4444"):
        self.grid_url = grid_url
    
    def get_grid_status(self):
        """获取Grid状态"""
        response = requests.get(f"{self.grid_url}/status")
        return response.json()
    
    def get_nodes_info(self):
        """获取所有节点信息"""
        response = requests.get(f"{self.grid_url}/graphql", json={
            "query": "query { nodes { id, uri, status, slots { id, session { id } } } }"
        })
        return response.json()
    
    def terminate_session(self, session_id):
        """终止指定会话"""
        response = requests.delete(f"{self.grid_url}/se/grid/session/{session_id}")
        return response.status_code == 200

# 使用示例
grid_manager = GridManager()
status = grid_manager.get_grid_status()
print(json.dumps(status, indent=2))

3. 实时监控和日志

python 复制代码
# 查看Grid日志(如果使用Docker)
docker logs -f selenium-hub

# 查看特定节点日志
docker logs -f selenium-chrome-node

六、最佳实践和故障排除

1. 最佳实践

  1. 使用适当的等待策略:Grid 环境中的网络延迟可能更高

  2. 实现重试机制:处理偶尔的网络问题

  3. 合理配置节点 :根据硬件资源设置 max-sessions

  4. 使用标签筛选:为节点添加标签,用于定向测试

  5. 监控资源使用:避免节点过载

2. 常见问题解决

问题:无法连接到 Hub

python 复制代码
# 添加连接超时和重试
from urllib3.exceptions import MaxRetryError

try:
    driver = webdriver.Remote(
        command_executor=grid_url,
        options=options,
        command_timeout=300  # 5分钟超时
    )
except MaxRetryError:
    print("无法连接到Grid Hub,请检查Hub是否运行")

问题:节点注册失败

python 复制代码
# 检查防火墙设置
# 确保Hub和Node之间的网络连通性
# 检查端口是否开放

问题:会话创建超时

python 复制代码
# 增加节点启动参数中的超时时间
java -jar selenium-server.jar node --session-timeout 600

3. 性能优化建议

python 复制代码
# 为每个节点分配适当的内存
java -jar selenium-server.jar node -Xmx4g

# 限制每个节点的最大会话数
java -jar selenium-server.jar node --max-sessions 5

# 使用更快的浏览器驱动
# 考虑使用chromedriver的--no-sandbox选项

七、高级特性

1. 自定义节点配置

创建 config.toml 配置文件:

python 复制代码
[node]
detect-drivers = false
max-sessions = 5
session-timeout = 300

[[node.driver-config]]
display-name = "Chrome"
stereotype = '{"browserName": "chrome", "browserVersion": "118", "platformName": "Linux"}'
max-sessions = 2

[[node.driver-config]]
display-name = "Firefox"
stereotype = '{"browserName": "firefox", "browserVersion": "118", "platformName": "Linux"}'
max-sessions = 2

然后使用配置文件启动:

bash 复制代码
java -jar selenium-server.jar node --config config.toml

2. 负载均衡和高可用

部署多个 Hub 实现高可用:

bash 复制代码
# 启动多个Hub实例
java -jar selenium-server.jar hub --port 4444
java -jar selenium-server.jar hub --port 4445

# 使用负载均衡器(如Nginx)分发请求

Selenium Grid 是构建大规模自动化测试基础设施的核心组件。通过合理配置和使用,你可以显著提升测试效率和覆盖率。记得根据实际需求选择合适的部署模式,并始终监控 Grid 的健康状态。

相关推荐
测试19987 小时前
单元测试到底是什么?该怎么做?
自动化测试·软件测试·python·测试工具·职场和发展·单元测试·测试用例
有技巧搬砖1 天前
ICT在线测试_ATE测试_FCT功能测试通用上位机
测试工具·治具·测试工装
币圈小菜鸟1 天前
Windows 环境下搭建移动端自动化测试环境(JDK + SDK + Node.js + Appium)
java·windows·python·测试工具·node.js·appium
霍格沃兹测试开发学社测试人社区2 天前
MCP零基础学习(7)|实战指南:构建论文分析智能体
人工智能·测试工具
测试老哥2 天前
如何用Postman做接口测试?
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman
程序员杰哥4 天前
Jmeter+Jenkins接口压力测试持续集成
自动化测试·软件测试·python·测试工具·jmeter·jenkins·压力测试
信而泰XINERTEL4 天前
如何用Renix实现网络测试自动化: 从配置分离到多厂商设备支持
测试工具·网络测试仪·测试软件
软测进阶4 天前
【第三章】软件测试缺陷管理:从判断到回归的全流程实践指南
测试工具·bug·源代码管理