selenium Grid详解

什么是selenium Grid

① Selenium Grid 是Selenium套件的一部分,它专门用于并行运行多个测试用例在不同的浏览器、操作系统和机器上。

② Selenium Grid 主要使用  master-slaves 或者  hub-nodes 理念 :一个  master/hub  和多个基于 master/hub 注册的子节点  slaves/nodes 。

当我们在master上基于不同的浏览器/系统运行测试用例时,master将会将测试用例分发给适当的node运行。(当然也可以作为兼容性测试工具将测试用例运行在不同的web浏览器上)

④ selenium Grid 主要的作用:实现分布式执行测试,解决浏览器兼容性问题。【通过 Selenium Grid 的可以控制多台机器多个浏览器执行测试用例,分布式上执行的环境在 Selenium Grid 中称为node节点。】

⑤举例:

当自动化测试用例达到一定数量的时候,比如上万,一台机器执行全部测试用例耗时5个小时(只是举例,真正的耗时是需要根据测试用例场景的复杂度决定的),而如果需要覆盖主流浏览器比如Chrome、Firefox,加起来就是10个小时;这时候领导跟你说有什么办法可以解决这个执行速度?当然最笨的办法就是另外拿台机器,然后部署环境,把测试用例分开去执行然后合并结果即可。而Selenium也想到了这点,所以有了Selenium Grid的出现,它就是解决分布式执行测试的痛点。

⑥总结:

  • Slenium Grid 分布式测试由hub主节点和node节点组成
  • Hub节点用来管理node节点注册信息。
  • 脚本——》Hub节点——》node节点——》浏览器

什么时候用Selenium Grid

①同时在不同的浏览器操作系统机器上运行测试。最大程度用于兼容性测试。

②减少测试用例的运行时间。

Selenium Grid工作原理

① Selenium Grid 实际它是基于Selenium RC的,而所谓的分布式结构就是由一个hub节点和若干个node代理节点组成。

②Hub节点用来管理各个代理节点的注册信息和状态信息,并且接受远程客户端代码的请求调用,然后把请求的命令转发给代理节点来执行

如何启动Selenium Grid

启动 Selenium Grid 有三种方式:一种直接用命令行方式;另一种用JSON配置文件;最后一种docker启动。

首先需要下载:selenium-server-standalone-3.9.1.jar【可以理解为搭建selenium Grid环境】

下载地址:http://selenium-release.storage.googleapis.com/index.html

1、命令行方式启动 selenium Grid 

①进入selenium-server-standalone-3.9.1.jar文件所在的目录位置。

②进入cmd命令行终端中。

③启动Hub,命令如下:

java -jar selenium-server-standalone-3.9.1.jar -role hub -maxSession 10 -port 4444

运行结果如下图:

命令参数解析:

  •  - role :此参数后跟hub或者node;表示此机器启动hub节点或者node子节点
  •  - port :此参数后跟端口号;设置启动hub或者node节点服务的端口号;hub的默认端口是4444;这里使用的是默认的端口,当然可以自己配置;
  •  - maxSession :此参数后跟最大会话请求数;最大会话请求,这个参数主要用于并发执行测试用例,默认是1,建议设置10及以上。

④浏览器打开地址:http://localhost:4444/grid/console,出现如下图表示hub节点启动成功。

⑤启动node节点【启动hub节点后最少需要一个node节点,不然启动hub节点就没有意义】

而node节点同样可以与hub节点在同一台机器上运行,如下例就是hub节点与node节点同机的例子。

hub机

ip:10.200.145.226

node1机

ip:10.200.145.226

命令行:

java -jar selenium-server-standalone-3.9.1.jar -role node -port 6666 -hub http://10.200.145.226:4444/grid/register/ -maxSession 5 -browser browserName=chrome,seleniumProtocol=WebDriver,maxInstances=5,platform=WINDOWS,version=96.0

运行结果如下图:

命令参数解析:

  •   -role node :表示启动的是node节点
  •   -port 5555 :指定node节点端口
  •  - browser :启动的node节点服务设置浏览器参数信息
  1.    browsderName=chrome :浏览器的名称
  2.    seleniumProtocol=WebDriver :selenium工具的实现协议
  3.    maxInstances=5 :最大实例(该node节点上最多可运行的浏览器数),该值不能大于前面开启hub节点服务时 maxSession 参数的值
  4.    platform=WINDOWS :表示操作系统。
  5.    version=96.0 :表示浏览器版本。
  6.    Dwebdriver.chrome.driver=chromedriver.exe  :浏览器驱动,如果是其他浏览器就写对应的浏览器驱动的名字;如火狐浏览器:  Dwebdriver.firefox.driver=geckodriver.exe 
  •  - hub :此参数后面跟开启hub节点时生成的Nodes节点应该连接的地址,表示需要连接的hub机地址

⑥浏览器重新打开地址:http://localhost:4444/grid/console,如出现下图则表示node节点服务启动成功:

【注意】如果使用的chromedriver.exe与selenium-server-standalone-3.9.1.jar版本或者浏览器chrome版本不匹配都会报错提示,具体原因需要具体解决。

2、Json配置文件启动 selenium Grid 

①创建hub的Json配置文件。

代码如下:将下述代码保存为 hub_config.json 文件,放在hub节点机器的与selenium server(即selenium-server-standalone-3.9.1.jar)相同的路径下。

{
  "port": 4444,
  "newSessionWaitTimeout": -1,
  "servlets" : [],
  "withoutServlets": [],
  "custom": {},
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "registry": "org.openqa.grid.internal.DefaultGridRegistry",
  "throwOnCapabilityNotPresent": true,
  "cleanUpCycle": 5000,
  "role": "hub",
  "debug": false,
  "browserTimeout": 0,
  "timeout": 1800
}

②创建nodes的Json配置文件。

代码如下:保存为 node_config.json 文件(注意将hub对应的值改为node节点机器的IP地主),放在node节点上和selenium server相同的路径下。(当多个node时需将该文件放在多个node机器上或者同一个机器上启动多个node)

{
  "capabilities":
  [
    {
      "browserName": "firefox",
      "marionette": true,
      "maxInstances": 5,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "internet explorer",
      "platform": "WINDOWS",
      "maxInstances": 1,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "safari",
      "technologyPreview": false,
      "platform": "MAC",
      "maxInstances": 1,
      "seleniumProtocol": "WebDriver"
    }
  ],
  "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
  "maxSession": 5,
  "port": -1,
  "register": true,
  "registerCycle": 5000,
  "hub": "http://192.168.1.100:4444",
  "nodeStatusCheckTimeout": 5000,
  "nodePolling": 5000,
  "role": "node",
  "unregisterIfStillDownAfter": 60000,
  "downPollingLimit": 2,
  "debug": false,
  "servlets" : [],
  "withoutServlets": [],
  "custom": {}
}

hub机器上命令行运行: java -jar selenium-server-standalone-3.141.59.jar -role hub -hubConfig hub_config.json 

node机器上命令行运行: java -jar selenium-server-standalone-3.141.59.jar -role node -nodeConfig node_config.json 

【注意】命令行方式启动 selenium Grid、Json配置文件启动 selenium Grid 两种方式的缺点:不易启动和维护

  • 每个node需要下载和配置依赖
  • java 进程占内存
  • 出现问题时需手动启动
  • 不易维护
  • 扩展性差

3、docker启动 selenium Grid 

docker简介

docker启动 Selenium Grid 

docker上已经有selenium官方的Selenium Grid镜像,只有你已经安装了docker,即可使用。

  • 启动hub:docker run -d -p 4444:4444 --name selenium-hub selenium/hub
  • 启动node(Chrome&&Firefox):
  •   
    • docker run -d --link selenium-hub:hub selenium/node-chrome 
    • docker run -d --link selenium-hub:hub selenium/node-firefox

运行命令将会下载内置镜像文件(包括java、Chrome、Firefox、selenium-server-standalone-XXX.jar 等运行selenium所需的环境);此时你可以访问:http://localhost:4444/grid/console

如果需要多个Chrome node则继续运行这个命令: docker run -d --link selenium-hub:hub selenium/node-chrome ,刷新则看到多了一个Chrome实例。

通过运行命令: docker ps ,显示正在运行的容器:

docker 组件启动 Selenium Grid 

selenium Grid通常需要启动一个hub,多个nodes像Chrome、Firefox等。我们可以把他们定义到一个文件中叫做 docker-compose.yml ,通过一个命令来整体启动,docker提供了一个这样的工具 –Docker-Compose

②安装docker-compose,一旦安装成功,则创建一个新的文件夹,创建文件  docker-compose.yml ,  docker-compose.yml 内容:

version: "3"
services:
  selenium-hub:
    image: selenium/hub
    container_name: selenium-hub
    ports:
      - "4444:4444"
  chrome:
    image: selenium/node-chrome
    depends_on:
      - selenium-hub
    environment:
      - HUB_PORT_4444_TCP_ADDR=selenium-hub
      - HUB_PORT_4444_TCP_PORT=4444
  firefox:
    image: selenium/node-firefox
    depends_on:
      - selenium-hub
    environment:
      - HUB_PORT_4444_TCP_ADDR=selenium-hub
      - HUB_PORT_4444_TCP_PORT=4444

docker-compose命令:

  • 运行命令启动(到docker-compose.yml路径下):docker-compose up -d
  • 查看启动是否成功:docker-compose ps
  • 创建更多实例:docker-compose scale chrome=5
  • 关闭命令:docker-compose down

浏览器打开http://localhost:4444/grid/console将会看到:

运行脚本的话直接运行就好(IP:http://localhost:4444/wd/hub) ,和上边两种的方法不太一样;不会有浏览器打开(容器内部运行),但是已经运行成功:

import unittest
from selenium import webdriver


class MyTestCase(unittest.TestCase):

    def setUp(self):
        ds = {'platform': 'ANY',
              'browserName': "chrome",
              'version': '',
              'javascriptEnabled': True
              }
        self.dr = webdriver.Remote('http://localhost:4444/wd/hub', desired_capabilities=ds)

    def test_something(self):
        self.dr.get("https://www.baidu.com")
        self.assertEqual(self.dr.name, "chrome")

    def test_search_button(self):
        self.dr.get("https://www.baidu.com")
        self.assertTrue(self.dr.find_element_by_id("su").is_displayed())

    def tearDown(self):
        self.dr.quit()


if __name__ == '__main__':
    unittest.main()

Selenium Grid 脚本执行(在node节点机器上执行)

单node节点单浏览器执行代码脚本:

import time

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

cap = dict(browserName="chrome", version="96.0", platform="WINDOWS")

# 初始化连接
driver = webdriver.Remote('http://10.200.145.226:4444/wd/hub', desired_capabilities=cap)
driver.get("https://www.baidu.com/")
driver.find_element(By.ID, "kw").send_keys("selenium grid")

print(driver.title)
time.sleep(2)
driver.quit()

单node节点多浏览器并行执行代码脚本:

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


def task(driver):
    driver.get("https://www.baidu.com/")
    driver.find_element(By.ID, "kw").send_keys("selenium grid")
    time.sleep(2)
    driver.quit()


def getDrivder(browser):
    # 浏览器描述
    cap = None
    # 判断浏览器种类
    if browser == "chrome":
        cap = webdriver.DesiredCapabilities.CHROME.copy()  # 该类封装了各个浏览器的运行参数
    elif browser == "firefox":
        cap = webdriver.DesiredCapabilities.FIREFOX.copy()
    # 重构浏览器描述
    cap["platform"] = "WINDOWS"
    # 返回驱动对象
    return webdriver.Remote('http://10.200.145.226:6666/wd/hub', desired_capabilities=cap)


if __name__ == '__main__':
    browsers = ("chrome", "firefox")
    for b in browsers:
        # 获取驱动
        driver = getDrivder(b)
        # 创建线程执行任务
        threading.Thread(target=task, args=(driver,)).start()

 

posted @ 2022-01-04 10:01  习久性成  阅读(8135)  评论(2编辑  收藏  举报