测试开发 | 跨平台设备管理方案 Selenium Grid

news2024/11/17 20:36:32

Selenium Grid 是 Selenium 的三大组件之一,它可以在多台机器上并行运行测试,集中管理不同的浏览器版本和浏览器配置。通过将客户端命令发送到远程浏览器的实例, Selenium Grid 允许在远程计算机 (虚拟或真实) 上执行 WebDriver 脚本. 它旨在提供一种在多台计算机上并行运行测试的简便方法。

官方文档:https://www.selenium.dev/

使用场景

场景一: 实现分布式执行测试,提高执行效率

比如:我们有 1000 条用例执行,如果在本机执行,一条用例耗时 100 秒,执行完成则需要大约 27 小时 1000*100/60/60=27个小时。如果让这些用例并发执行,比如分配 6 台计算机,每个计算机执行 1000/6 大约 166 条用例,那时间大约节省了 6 倍,原来需要大约 27 个小时,现在可能只需要 4.5 个小时左右就基本完成了, 分布式并发执行可以让我们用例的执行总时长指数级的缩小,从而效率得到很大的提升。

场景二: 解决浏览器兼容性问题

比如还是 1000 条用例,需要分别在 Chrome、Firefox、Edge、Safari 这些浏览器上都执行一遍,保证每个浏览器上都能正常执行,测试浏览器的兼容性。这时也可以使用 Selenium Grid,通过 Selenium Grid 将这些请求分发到不同的系统、不同浏览器中执行。这些浏览器可以分别布署在不同的计算机中比如可以布署在 Linux 、Windows、Mac 上都可以,作为它的 Node 结点,从而解决兼容性测试的问题

新特性

Selenium Grid 4 是一个全新的工具,它能够支持完全分布式的测试。Selenium Grid4 也兼容了之前 Selenium Grid3 的工作模式,在 Selenium Grid3 的基础上又添加了一些新的通讯方式,使它通讯速度更快。另外现在很多公司都支持容器化部署,Selenium Grid 4 也提供了的 Docker 支持。相比 Selenium Grid 3,Selenium Grid 4 更容易在虚拟机上使用。

Selenium Grid4 有三个新特性

  • 特性一:Hub 和 Node 使用同一个 jar 服务。

  • 特性二:架构优化,在 Selenium Grid 4 版本的全新架构中划分成了组件:Router、Distributor、Node、Session Map、Session Queue、Event Bus。

  • 特性三:支持不同的运行模式,Selenium 4 支持三种网格类型,包括 Standalone Mode 独立模式、Classical Grid 经典网格模式、Fully Distributed 完全分布式

原理分析

下面这张图是官方提供的 Selenium Grid4 的工作原理图:

从图中可以看到 Selenium Grid 包括六大组件,分别是:

  • Router 路由器

  • Distributor 分发服务器

  • Session Map 会话映射

  • Node 测试节点

  • New Session Queue 新的会话队列

  • Event Bus 事件总线

下面分别说一下这六个组件所负责的职责:

  • Router 路由器:Router 是所有组件的入口,所有向服务器发送的外部请求第一个会经常 Router 组件。

  • Distributor 分发服务器:它有两个主要的功能,第一个功能,注册并跟踪所有 Node 节点,第二个功能就是查询新会话队列并处理挂起的新会话请求。当一个新的请求到达 Router 时,它会被转发到 New Session Queue,在队列中等待。分发服务器会轮询新会话队列查找挂起的新会话请求,为这个请求找到匹配的节点之后,会创建一个新的会话,这个会话的 ID 以及 URI 会存储在 Session Map 中。

  • Session Map 会话映射:它是一个数据存储区,它存储了会话 ID 与对应的会话结点的关系,在 Router 转发请求到对应的结点时,要先在 Session Map 中查看对应的关系,再进行请求。

  • Node 测试节点:结点有多个,每个结点管理多个可用的浏览器的插槽,结点只负责执行命令,不需要做出其它的判断。这个 Node 可以配置在 Windows、Mac、Linux 等任何系统上。

  • New Session Queue 新的会话队列:从 Router 发过来的请求,它会先放到这个队列中, 等待被分发服务器分发出去,这个队列有一些特殊的功能,它能够定期的检查会话是否超时,如果超时,请求将被拒绝并立即删除。这里可以配置一些参数来处理超时时长等参数。

  • Event Bus 事件总线:充当了节点、分发服务器、新会话队列和会话映射之间的通信路径,使用了 socket 通信。在完全分布式模式下启动 selenium grid 时,事件总线会是第一个被启动起来的组件。

环境安装

  • Java11 及以上版本。

  • 下载被测试的浏览器(Chrome/Firefox/Edge/Safari 等)。

  • 配置环境变量,将对应的 driver 提前下载下来配置到环境变量中。或者将下载的 driver 放在与 selenium server 的 jar 包同级目录下也可以。

  • Selenium Server 下载,建议使用 4.4.0 版本。

运行方式

单机运行 - 独立模式

1. 命令行启动 server

  1. 命令行 cd 到当前下载 jar 包的路径下

    cd Desktop
  2. java -jar 启动对应的 jar 包:java -jar selenium-server-<version>.jar standalone

    java -jar selenium-server-4.4.0.jar standalone

    启动成功后,对应命令行显示:Started Selenium Standalone ...,如图

  1. 查看 UI 界面 > 浏览器输入网址查看 UI 界面:UI 链接

  1. 查看 Grid status 状态 > 浏览器输入网址查看 status 状态:Status 状态

2. 代码运行

直接运行代码,发现在本地运行单线程,只不过通过 Selenium Grid 来转发请求。

运行步骤

  1. SeleniumGrid 会创建一个 Queue 队列,里面包含了启动的参数代码: 

  2. SeleniumGrid 创建一个本地的 session,然后再打开浏览器运行测试用例: 

单浏览器运行代码

示例代码如下:

"""
@Author: 霍格沃兹测试开发学社-西西
@Desc: '更多测试开发技术探讨,请访问:https://ceshiren.com/t/topic/15860'
"""
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By

class TestSingleNode:
    def setup_method(self):
        # 创建Options ,新版本DesireCapability已弃用
        options = webdriver.EdgeOptions()
        # 通过URL和options 创建一个远程的连接
        # client 发送请求,要发送给selenium grid hub 结点, hub 结点会将请求分发到对应的node

        self.driver = webdriver.Remote(
            command_executor='http://10.1.1.104:4444',
            options=options
        )

    def test_singlenode1(self):
        # 打开 baidu 页
        self.driver.get("http://www.baidu.com")
        # 向输入框中输入
        self.driver.find_element(By.ID, 'kw').send_keys("firefox")
        # 点击搜索框
        self.driver.find_element(By.ID, 'su').click()
        # 等待一秒
        sleep(1)
        # 断言输入内容在页面中
        assert "firefox" in self.driver.page_source

    def teardown_method(self):
        self.driver.quit()

多浏览器运行代码

创建测试文件 test_multi_node.py 示例代码如下:

from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By

class TestMultiNode:
    def setup_method(self):
        options = webdriver.ChromeOptions()
        self.driver = webdriver.Remote(
            command_executor='http://10.1.1.104:4444',
            options=options
        )

    def test_multinode1(self):
        # 打开 baidu 页
        self.driver.get("http://www.baidu.com")
        # 向输入框中输入
        self.driver.find_element(By.ID, 'kw').send_keys("selenium")
        # 点击搜索框
        self.driver.find_element(By.ID, 'su').click()
        # 等待一秒
        sleep(1)
        # 断言输入内容在页面中
        assert "selenium" in self.driver.page_source

    def test_multinode2(self):
        # 打开 baidu 页
        self.driver.get("http://www.baidu.com")
        # 向输入框中输入
        self.driver.find_element(By.ID, 'kw').send_keys("appium")
        # 点击搜索框
        self.driver.find_element(By.ID, 'su').click()
        # 等待一秒
        sleep(1)
        # 断言输入内容在页面中
        assert "appium" in self.driver.page_source

    def test_multinode3(self):
        # 打开 baidu 页
        self.driver.get("http://www.baidu.com")
        # 向输入框中输入
        self.driver.find_element(By.ID, 'kw').send_keys("pytest")
        # 点击搜索框
        self.driver.find_element(By.ID, 'su').click()
        # 等待一秒
        sleep(1)
        # 断言输入内容在页面中
        assert "pytest" in self.driver.page_source

    def test_multinode4(self):
        # 打开 baidu 页
        self.driver.get("http://www.baidu.com")
        # 向输入框中输入
        self.driver.find_element(By.ID, 'kw').send_keys("requests")
        # 点击搜索框
        self.driver.find_element(By.ID, 'su').click()
        # 等待一秒
        sleep(1)
        # 断言输入内容在页面中
        assert "requests" in self.driver.page_source

    def test_multinode5(self):
        # 打开 baidu 页
        self.driver.get("http://www.baidu.com")
        # 向输入框中输入
        self.driver.find_element(By.ID, 'kw').send_keys("java")
        # 点击搜索框
        self.driver.find_element(By.ID, 'su').click()
        # 等待一秒
        sleep(1)
        # 断言输入内容在页面中
        assert "java" in self.driver.page_source

    def teardown_method(self):
        self.driver.quit()

为了模拟多浏览器并发运行,使用 pytest 的插件 pytest-xdist 实现分布式并发执行方式,提前安装 pytest-xdist 插件,然后使用命令执行用例。打开命令提示行或者终端,使用cd 命令进入到文件所在路径,然后执行 pytest test_multi_node.py -n 3 --alluredir ./results命令。执行完用例之后,会把测试报告结果统一汇总到results 目录中。

单机运行 - 经典网格模式

1. 命令行启动 hub

  1. 命令行 cd 到当前下载 jar 包的路径下

    cd Desktop
  2. java -jar 以 Hub 启动对应的 jar 包:java -jar selenium-server-<version>.jar hub

    java -jar selenium-server-4.4.0.jar hub

此时,启动了 Router,Distributor,Session Map,New Session Queue,Event Bus;虽然,已经有了对应集线器,但是还没有 node 节点注册进来。
如果不把节点 Node 注册进来,对应的集线器无法知道哪个物理机器可以被分发请求,对应的 Router 就无法把测试用例进行分发。

 3. 查看状态的 UI 界面: 

2. 命令行启动 node

  1. 同一机器上启动 node:java -jar selenium-server-<version>.jar node --detect-drivers true

    java -jar selenium-server-4.4.0.jar node --detect-drivers true

此时 node 节点创建成功,并且 hub 上注册对应 node 节点:

健康检测就是每隔 2 分钟会 ping 一下对应 URL 看看是否可以 ping 成功,对应是否处于活动状态

2. 再次查看状态的 UI 界面:

3. 代码运行

直接运行代码,发现在本地运行单线程,只不过通过 Selenium Grid 来转发请求。

多系统运行 - 分发模式

在经典网格模式等基础上再在其他机器上启动一个 node 角色。

1. 不同机器上启动 node

  1. 不同机器上启动 node:java -jar selenium-server-<version>.jar node --detect-drivers true --publish-events tcp://<ip> --subscribe-events tcp://<ip>

    java -jar selenium-server-4.4.0.jar node --detect-drivers true --publish-events tcp://10.1.1.178:4442 --subscribe-events tcp://10.1.1.178:4443

    此时 node 节点创建成功,并且在远端 hub 上注册对应 node 节点

  2. 查看状态的 UI 界面: 

注意⚠️:不同机器上启动的时候需要安装相同版本的 jar 及根据机器上的浏览器下载对应的 driver

2. 不同机器上运行用例

使用代码运行时会发现对应分发时会分给不同的系统运行代码,如图: 

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

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

相关文章

SSL证书的类型

SSL证书类型分3类&#xff1a;DV OV EV.域名型&#xff08;DV&#xff09;SSL证书: 信任等级一般&#xff0c;只需验证网站的真实性便可颁发证书保护网站。企业型&#xff08;OV&#xff09;SSL证书: 信任等级强&#xff0c;须要验证企业的身份&#xff0c;审核严格&#xff0c…

VS2017基于CLR运行环境的VC++.NET界面编程(数据库为mysql)

此篇献给暨南大学珠海校区还在用VS2013编写VC++.NET界面程序的苦逼们! 文章分为四个部分: 1、运行环境的搭建 2、数据库的连接 3、控件介绍 4、程序编写示例 程序效果演示视频和程序源码及数据库文件附于文末。 一、运行环境的搭建 VS自从2013版本后淘汰VC++.NET,编写界面…

恒星物联河道流量监测站——雷达流量计

一、产品概述 河道流量监测站是一款采用一体化设计的河道流量智能监测设备&#xff0c;设备由河道雷达流量计、遥测终端机、太阳能供电系统组成。雷达流量计采用先进的K波段平面雷达技术&#xff0c;通过非接触的方式测量水体的流速和水位&#xff0c;根据内置的软件算法&…

TCP协议重点总结(万字总结-附实例)

文章目录前言一、网络的原生情况二、TCP协议2.1 TCP的特点2.2 TCP协议段格式2.3 TCP原理2.3.1 确认应答机制&#xff08;可靠机制&#xff09;2.3.2 序列号2.3.3 超时重传机制&#xff08;可靠机制&#xff09;2.3.4 连接管理机制&#xff08;可靠机制&#xff09;2.3.5 滑动窗…

RabbitMQ的简介和简单使用

同步调用异步调用MQRabbitMQ的使用docker拉取docker pull rabbitmq:3-management启动容器docker run \-e RABBITMQ_DEFAULT_USERitcast \ &#xff08;账号&#xff09;-e RABBITMQ_DEFAULT_PASS123321 \ &#xff08;密码&#xff09;--name mq \--hostname mq1 \-p 15672:156…

开发工具中SpringBoot使用外置Tomcat启动 (亲测有效)-第458篇

历史文章&#xff08;文章累计450&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 SpringBoot添加外部jar包及打包(亲测有…

评测5款国内外免费远控,谁是最好用第一名?

远程控制应用不少人都有了解使用过&#xff0c;尤其是会常用电脑进行工作的群体&#xff0c;比如程序员、设计师、运维、文员等岗位。在隔离居家远程办公时&#xff0c;通过家里的手机、平板或电脑跨系统、跨设备操控公司所用的办公电脑&#xff0c;就能及时处理工作内容&#…

前端使用lottie-web,使用AE到处的JSON动画贴心教程

Lottie简介 官方介绍&#xff1a;Lottie是一个库&#xff0c;可以解析使用AE制作的动画&#xff08;需要用bodymovie导出为json格式&#xff09;,支持web、ios、android、flutter和react native。 在web端&#xff0c;lottie-web库可以解析导出的动画json文件&#xff0c;并将其…

02_FreeRTOS移植

目录 获取FreeRTOS源码 FreeRTOS源码内容 FreeRTOS内核 Demo文件夹 Source文件夹 portable文件夹 FreeRTOS移植 移植步骤 移植详解 实验源码: 获取FreeRTOS源码 FreeRTOS官网:https://www.freertos.org/ FreeRTOS源码内容 FreeRTOS内核 Demo文件夹 Demo文件夹里面就…

《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》中文分享(15)

《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》 本人能力有限&#xff0c;如果错误欢迎批评指正。 第四章&#xff1a;Protein Binding Leads to Biological Actions &#xff08;蛋白质的结合会产生生物作用&#xff09; 如果我们想要对一个结合过…

Java 泛型中的通配符详解

目录 1、如何定义和使用上界通配符&#xff1f; 2、如何定义和使用无界通配符&#xff1f; 3、如何定义和使用下界通配符&#xff1f; 4、如何使用通配符定义泛型类或接口之间的子类型关系&#xff1f; 5、通配符的捕获和辅助方法 6、通配符使用指南 在泛型代码中&#x…

C++ txt文本文件处理系统(c++学习小例子)

C++ txt文本文件处理系统(c++学习小例子) 一、界面示例二、 要求2.1 数据格式2.2 实现功能三、代码3.1 classfi.h3.2 classfi.cpp3.3 main.cpp四、 使用说明一、界面示例 二、 要求 2.1 数据格式 现有DEM数据,其格式为DEM_data.txt,可在文章末尾下载。文本存储格式如下: …

用javascript分类刷leetcode19.数组(图文视频讲解)

数组操作的时间复杂度 Access&#xff1a;O(1) Search&#xff1a;O(n) Insert&#xff1a; 平均O(n)&#xff0c;最好的情况下O(1)&#xff0c;也就是在数组尾部插入O(1)&#xff0c;最坏的情况下O(n) Delete&#xff1b;平均O(n)&#xff0c;最好的情况下O(1)&#xff0c;…

力扣刷题记录——367. 有效的完全平方数、383. 赎金信、387. 字符串中的第一个唯一字符、389. 找不同

本专栏主要记录力扣的刷题记录&#xff0c;备战蓝桥杯&#xff0c;供复盘和优化算法使用&#xff0c;也希望给大家带来帮助&#xff0c;博主是算法小白&#xff0c;希望各位大佬不要见笑&#xff0c;今天要分享的是——《367. 有效的完全平方数、383. 赎金信、387. 字符串中的第…

LightDB单机安装

LightDB单机安装 LightDB官网&#xff1a;https://www.hs.net/lightdb 下载安装包&#xff1a;lightdb-x-13.8-22.3-7953-el7.x86_64.zip 前置准备 防火墙配置(选择一种操作) firewall防火墙 firewall-cmd --permanent --add-port5432/tcp firewall-cmd --permanent --add-p…

(深度学习快速入门)第三章第三节2:深度学习必备组件之损失函数和激活函数

文章目录一&#xff1a;损失函数&#xff08;1&#xff09;均方误差损失&#xff08;MSE&#xff09;&#xff08;2&#xff09;交叉熵损失&#xff08;Cross Entropy&#xff09;二&#xff1a;激活函数&#xff08;1&#xff09;tanh&#xff08;2&#xff09;ReLU&#xff0…

SpringBoot数据响应与内容协商

目录 数据响应与内容协商 1、响应JSON 1.1、jackson.jarResponseBody 1.2、SpringMVC到底支持哪些返回值 2、内容协商 1、引入xml依赖 2、postman分别测试返回json和xml 3、开启浏览器参数方式内容协商功能 数据响应与内容协商 1、响应JSON 1.1、jackson.jarResponseBo…

区块链北大肖老师学习笔记6

第七节 比特币的挖矿难度调整 H(block header) < target 目标(target)预值越小&#xff0c;挖矿的难度越大。调整挖矿的难度就是调整目标空间在整个输出空间中所占的比例。 比特币用的哈希算法是SHA-256&#xff0c;这个产生的哈希值是256位。所以整个输出空间是2的256次…

[JavaEE]synchronized 与 死锁

专栏简介: JavaEE从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录 1.synchronized 的特性 2. synchronized 使用示例:…

new做了什么

function structure (name, age) {this.name namethis.age age}// 给构造函数--prototype加上一个方法structure.prototype.sayName function () {console.log(this.name, 调用打印);return this.name}structure.one 5const person new structure(张龙, 188)// 打印构造函…