【Selenium】Selenium4 Grid

news2024/11/19 4:14:58

Selenium Grid: 将客户端发送的命令转发到远程浏览器上执行 WebDriver 脚本。

简介

Selenium Grid 是由一个 hub 服务和若干个 node 代理节点组成。

Hub 调度服务,管理各个代理节点的注册信息和状态信息,并且接收来自客户端代码的调用请求,把请求的命令转发给代理节点执行。

Node 代理节点,相当于一台可以运行浏览器自动化测试的机器,根据 hub 的命令执行脚本。

  • 支持在多台机器上并行测试
  • 支持在不同的浏览器版本上进行测试
  • 支持跨平台测试

执行流程

  1. 运行代码初始化 driver 时,配置远程浏览器为 hub 服务 + 端口;
  2. 服务端收到代码请求后转为执行命令,分发给不同的 node(浏览器);
  3. node 根据收到的命令执行测试;
  4. 测试完成后返回结果给 hub
  5. hub 收集结果返回给客户端。

搭建

整套环境搭建可以通过两种方式:

  • *.jar(太麻烦且不易维护)
  • docker(官方镜像支持,即插即用)

Docker 简单好用,由于要启动多个服务,这里使用工具 docker-compose 进行部署。

1. 编写配置文件

新建目录下创建配置文件 compose.yml,用来定义初始化容器的配置。

# ref: https://github.com/SeleniumHQ/docker-selenium
version: "3"
services:
  chrome:
    image: selenium/node-chrome:4.6.0-20221104
    shm_size: 2gb  # 设置共享内存,官方建议值,避免浏览器引起容器崩溃
    depends_on:    # 设置依赖关系
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443

  firefox:
    image: selenium/node-firefox:4.6.0-20221104
    shm_size: 2gb
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443

  selenium-hub:
    image: selenium/hub:4.6.0-20221104
    container_name: selenium-hub
    ports:
      - "4442:4442"
      - "4443:4443"
      - "4444:4444"
2. 启动服务
# 进入配置文件所在的目录下
# 该目录下尽量别放其他东西,影响启动性能
$ cd seleniumgrid

# -d 后台启动
$ docker-compose up -d
Creating network "seleniumgrid-compose_default" with the default driver
Creating selenium-hub ... done
Creating seleniumgrid-compose_firefox_1  ... done
Creating seleniumgrid-compose_chrome_1 ... done

根据日志可以看到,首先创建桥接网络,每个容器都会自动加入该网络中,便于服务间互相通信;然后再启动 Hub 容器,根据依赖关系,继续启动节点容器。

同一服务配置,支持启动多个容器节点。注意:如果要启动多节点的话,配置文件内不要定义容器端口号,避免冲突。

# 启动多节点
$ docker-compose up -d --scale chrome=2 --scale firefox=2
Creating selenium-hub ... done
Creating seleniumgrid-compose_firefox_1 ... done
Creating seleniumgrid-compose_firefox_2 ... done
Creating seleniumgrid-compose_chrome_1  ... done
Creating seleniumgrid-compose_chrome_2  ... done

# 停止并删除容器&网络
# stop 指令仅停止不删除
$ docker-compose down
3. 验证

访问服务端: http://localhost:4444,可以看到启动的节点信息,即为成功。

image-20221122173737391

运行

编写测试脚本,在远程节点上运行。

import pytest
from time import sleep
from selenium import webdriver

"""
初始化 chrome | firefox driver
"""
@pytest.fixture(scope='session')
def driver():
    options = webdriver.ChromeOptions()
    driver = webdriver.Remote(
        command_executor='http://localhost:4444/wd/hub',
        options=options
    )
    yield driver
    driver.quit()

@pytest.fixture(scope='session')
def firefox_driver():
    firefox_options = webdriver.FirefoxOptions()
    driver = webdriver.Remote(
        command_executor='http://localhost:4444/wd/hub',
        options=firefox_options
    )
    yield driver
    driver.quit()
    
"""
测试执行:2 条用谷歌浏览器,2 条用火狐浏览器
测试用例:访问百度首页,在页面停止一秒。
"""
URL = "https://baidu.com"
TITLE = "百度一下,你就知道"

def test_chrome(driver):
    driver.get(URL)
    sleep(1)
    assert driver.title == TITLE

def test_chrome2(driver):
    driver.get(URL)
    sleep(1)
    assert driver.title == TITLE

def test_firefox(firefox_driver):
    firefox_driver.get(URL)
    sleep(1)
    assert firefox_driver.title == TITLE

def test_firefox2(firefox_driver):
    firefox_driver.get(URL)
    sleep(1)
    assert firefox_driver.title == TITLE

用例运行完成后,观察 hub 界面展示,会看到节点运行状态与 session 信息。 由于是单线程运行,所以会有两个闲置节点。

单线程运行测试用例
hello.py::test_chrome 
hello.py::test_chrome2 
hello.py::test_firefox 
hello.py::test_firefox2 
===== 4 passed in 143.25s =====
并发执行测试用例
# 两节点并发
$ pytest hello.py -n 2 -vs
...
[gw1] PASSED hello.py::test_chrome2 
[gw0] PASSED hello.py::test_chrome  
[gw1] PASSED hello.py::test_firefox2 
[gw0] PASSED hello.py::test_firefox 
===== 4 passed in 42.20s =====

# 四节点并发
$ pytest hello.py -n 4 -vs
...
[gw1] PASSED hello.py::test_chrome2 
[gw0] PASSED hello.py::test_chrome 
[gw3] PASSED hello.py::test_firefox2 
[gw2] PASSED hello.py::test_firefox 
===== 4 passed in 27.21s =====

根据运行时间,可以看到,并发测试会明显缩短耗时。实际项目中,需注意规避用例间的依赖问题。

Debugging

浏览器运行在容器内,本地看不到用例执行过程。为方便调试,代理节点允许用户查看容器内浏览器的执行过程。

实现此功能需要将浏览器端口暴露出来,注意主机端口号不要重复,可以按序增加。

比如:

  • Chrome : port=7900
  • Firefox: port=7901

compose.yml 内增加端口号,修改后重新启动服务。

# VNC Viewer
version: "2"
services:
  chrome:
    image: selenium/node-chrome:4.6.0-20221104
    shm_size: 2gb  # 设置共享内存,官方建议值,避免浏览器引起容器崩溃
    depends_on:  # 设置依赖关系
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
      - SE_VNC_NO_PASSWORD=1  # 取消 VNC 密码,默认密码 secret
    ports:
      - "5900:5900"  # VNC Server
      - "7900:7900"  # noVNC Web 

  firefox:
    image: selenium/node-firefox:4.6.0-20221104
    shm_size: 2gb
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
    ports:
      - "5901:5900"
      - "7901:7900"

  selenium-hub:
    image: selenium/hub:4.6.0-20221104
    container_name: selenium-hub
    ports:
      - "4442:4442"
      - "4443:4443"
      - "4444:4444"
方式一:VNC Viewer Client

该项目使用 x11vnc 作为 VNC 服务器,通过 VNC Viewer 客户端建立连接后,可实时查看容器内运行情况。

  • 新建连接 Command+N
  • VNC Server: IP/Host:Port
  • Name: 自定义

如果未添加无需密码的配置项,则需要输入默认密码 secret 后建立连接。

方式二:noVNC Web

基于 noVNC 可以直接在本机浏览器上查看容器内的运行情况,无需安装客户端。

访问配置的端口服务即可:

  • Chrome: http://localhost:7900
  • Firefox: http://localhost:7901

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/29590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

13.练习题(年月日,打字游戏)

练习 1.任意给出一个年、月、日,判断是这一年的第几天:闰年算法:能被4整除且不能被100整除,或者能被400整除。 如:2012 5 10 是这一年的第131天。 提示:使用数组的方式计算,将每月的天数放在一…

面试学习总结

之前根据视频做的总结,备个份。 一、Volatile关键字 volatile是Java虚拟机提供的轻量级的同步机制。 三个特性: 保证可见性 线程修改了工作内存中的值并写回到主内存之后,主内存立刻通知所有线程。称为可见性。(结合JMM理解&am…

蓝桥杯刷题(三)

蓝桥杯刷题一.等差素数列(较难)二.货物摆放(思路新奇)三.既约分数四.跳跃五.数值求值(坑题)蓝桥杯题库一.等差素数列(较难) 这道题有公式,其等差就是它长度内所有素数的乘…

Seata安装并注册集成到Nacos服务上

目录 一.工具地址与版本 二.解压与配置 三.创建数据库,执行脚本 四.启动与调试 五.seata高可用 六.查看启动情况 一.工具地址与版本 1.nacos-server-2.0.3 下载地址:Releases alibaba/nacos GitHub 2.seata-server-1.4.2 下载地址&#xff1…

小侃设计模式(十四)-职责链模式

1.概述 责任链模式(Chain of Responsibility Pattern)是为请求创建了一个接收者对象的链,让请求沿着这条链进行传播,直到有对象处理它为止,它属于典型的行为型模式。这种方式降低了发送者和处理者之间的耦合关系&…

HTML+CSS简单的网页制作期末作业 关于我的家乡——四川文化网页介绍 DW大学生网页作业制作设计 Dreamweaver简单网页成品

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法,如盒子的嵌套、浮动、margin、border、background等属性的使用,外部大盒子设定居中,内部左中右布局,下方横向浮动排列,大学学习的前端知识点和布局方式都有…

chapter1——亚稳态的世界

目录1.亚稳态理论2.亚稳态窗口3.计算MTBF4.避免亚稳态多级同步器时钟倍频电路的多级同步器5.亚稳态测试电路6.同步器类型7.综合性建议在异步系统中,由于数据和时钟的关系不是固定的,因此有时会出现违反建立和保持时间的现象,此时便会输出介于…

OTA: Optimal Transport Assignment for Object Detection原理与代码解读

paper:OTA: Optimal Transport Assignment for Object Detection code:https://github.com/Megvii-BaseDetection/OTA 背景 标签分配(Label Assignment)是目标检测中重要的一环,经典的标签分配策略采用预定义的规则…

Type-challehges learning: pick

type-challenges/README.zh-CN.md at main TIMPICKLE/type-challenges GitHub 最近真的是迷上了type-challenges。无法自拔 TS真是太香了&#xff01; 今天手写一个pick 从类型定义的属性中&#xff0c;选取指定一组属性&#xff0c;返回一个新的类型定义。 type Pick<T…

Npm——发布依赖库并使用

1. 注册一个NPM账号 npm官方地址&#xff1a;https://www.npmjs.com/ 2. 在本地创建一个目录,输入npm初始化命令&#xff0c;并修改package.json,创建src/index.js入口文件 npm init --yespackage.json name npm发布时的包名&#xff0c;和已有的npm库不能重复version 包版本…

网络安全——SQL注入之安全狗bypass深度剖析

作者名&#xff1a;Demo不是emo 主页面链接&#xff1a;主页传送门 创作初心&#xff1a;舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座…

这些调试API技巧你熟悉吗?

通常&#xff0c;我们在调试第三方提供的API时&#xff0c;有时候并没那么顺畅&#xff0c;甚至可能本身就是API服务有问题&#xff0c;但是需要提供你结论的"依据"。下面整理了一些API调试技巧&#xff0c;也方便你甩锅 简单来说分为以下两点 检测状态信息检测返回…

MySQl(八):索引机制

MySQl&#xff1a;索引索引概述索引结构B树的演变过程B树Hash索引分类聚集索引和二级索引### 回表查询思考索引语法普通索引联合索引删除索引索引使用索引使用规则之验证索引效率索引使用规则之最左前缀法则索引使用规则之索引失效情况索引使用规则之SQL提示索引使用规则之覆盖…

java多线程

最近看了寒食君的java多线程的教程&#xff0c;感觉深受启发&#xff0c;做个笔记以后方便回忆。 寒食君的个人空间-寒食君个人主页-哔哩哔哩视频 java多线程 什么是线程模型? JVM线程与操作系统线程之间存在着某种映射关系&#xff0c;这两种不同维度的线程之间的规范和协…

SpringCloud微服务(十)——Hystrix服务降级熔断限流

Hystrix服务降级熔断限流 SpringCloud&#xff0c;已停更 前言 分布式系统面临的问题&#xff0c;复杂分布式体系结构中的应用程序&#xff0c;有数10个依赖关系&#xff08;feign调用&#xff09;, 每个依赖关系在某些时候将不可避免地失败。低耦合就是微服务之间关系少。当…

pytorch初学笔记(十):神经网络基本结构之最大池化的使用

目录 一、最大池化&#xff1a;下采样 1.1 参数介绍 1.2 公式 二、最大池化的作用和目的 三、代码实战 3.1 题目要求 3.2 池化的具体实现 3.2.1 步骤 3.2.2 报错及其原因 3.2.3 ceil_mode不同运行的结果不同 3.2.4 完整代码 3.3 tensorboard可视化 一、最大池化&…

【强化学习论文合集】AAMAS-2022 强化学习论文 | 2022年合集(三)

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

相控阵天线(六):直线阵列特殊综合方法(变形泰勒综合法、贝利斯综合法、伍德沃德抽样法)

目录简介变形泰勒综合法贝利斯综合法伍德沃德-劳森抽样法配相抵消法简介 阵列天线的综合问题是其分析的逆问题&#xff0c;即是在预先给定辐射特性(如方向图形状、副瓣电平等)的情况下&#xff0c;综合出阵列激励幅度和相位。其中特殊综合主要包括&#xff1a;左右副瓣电平不相…

关于Idea合并不同分支代码你怎么看

一、环境说明 1. IDEA版本 2020.1 2. git版本 2.33.0 二、整体合并 1. 软件开发中&#xff0c;在一次版本迭代过程中&#xff0c;大家可能会在同一个开发分支dev进行开发&#xff0c;同时开发不同功能 &#xff0c;开发完以后需要自行合并到测试分支test&#xff0c;交给测试…

Feign高级实战-源码分析

目录参考导读什么是FeignFeign 和 Openfeign 的区别OpenFeign的启动原理在启动类申明EnableFeignClientsregisterDefaultConfigurationregisterFeignClientsregisterFeignClientgetTarget()创建一个代理对象HttpClientFeignLoadBalancerConfigurationOpenFeign 的工作原理动态代…