Selenium Grid优点
传统的web测试环境是先装一个浏览器,然后下载对应浏览器对应版本的启动,然后自动化程序中写如下一行
driver = webdriver.Chrome(executable_path="C:\\python37\\chromedriver.exe",chrome_options=browser_options)
传统测试框架有两个弊端:
- 不易部署、升级和卸载。假设测试环境有10台机器,如果需要升级浏览器,则需要每台登上去折腾一番,然后把驱动换了。即使使用配置管理工具,维护起来也麻烦。如果你想从火狐换成谷歌浏览器,是不是一台一台卸载?
- 负载不均衡,伤硬件。大公司如果测试工作量大,如何做到10台机器每台都能执行差不多量的任务,负载均衡,而不是总薅一只羊的羊毛?如果有的部门都把测试放到一台上执行,机器内存泄漏怎么办?
- 测试环境隔离性差。如果有人登录了测试环境并操作,可能影响测试甚至导致测试中断。
搭建Grid能解决这些问题。
Selenium Grid环境搭建
找一台性能较好,有固定ip的机器,开始搭建。
第一步:安装Docker
docker支持windows、Mac、linux。各个平台安装方法参考官方文档: https://docs.docker.com/get-docker/ 我以CentOS为例,以下安装方法支持CentOS全系列(7,8)。
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum-config-manager --enable docker-ce-nightly
sudo yum-config-manager --enable docker-ce-test
sudo yum install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
docker version
在Centos8中安装docker有时会报错,提示包已存在。其实是系统包太旧了和docker yum源中的新版本冲突,手动直接把这个报错的旧包卸载掉,然后重新执行安装命令。
sudo yum -y remove xxxx
第二步:安装docker-compose命令
以下安装方法支持所有Linux系统。
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
第三部:保存yaml文件
以下代码请保存成docker-compose-v3-full-grid.yml 这篇代码来源于github上的docker-selenium项目,进行了适当改造 原文:https://github.com/SeleniumHQ/docker-selenium/blob/trunk/docker-compose-v3-full-grid.yml 请根据自己的需要改造里面的Node配置,也可以不改,直接用即可。
version: "3"
services:
selenium-event-bus:
image: selenium/event-bus:4.0.0-rc-1-prerelease-20210618
container_name: selenium-event-bus
ports:
- "4442:4442"
- "4443:4443"
- "5557:5557"
selenium-sessions:
image: selenium/sessions:4.0.0-rc-1-prerelease-20210618
container_name: selenium-sessions
ports:
- "5556:5556"
depends_on:
- selenium-event-bus
environment:
- SE_EVENT_BUS_HOST=selenium-event-bus
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
selenium-session-queue:
image: selenium/session-queue:4.0.0-rc-1-prerelease-20210618
container_name: selenium-session-queue
ports:
- "5559:5559"
depends_on:
- selenium-event-bus
environment:
- SE_EVENT_BUS_HOST=selenium-event-bus
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
selenium-distributor:
image: selenium/distributor:4.0.0-rc-1-prerelease-20210618
container_name: selenium-distributor
ports:
- "5553:5553"
depends_on:
- selenium-event-bus
- selenium-sessions
- selenium-session-queue
environment:
- SE_EVENT_BUS_HOST=selenium-event-bus
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_SESSIONS_MAP_HOST=selenium-sessions
- SE_SESSIONS_MAP_PORT=5556
- SE_SESSION_QUEUE_HOST=selenium-session-queue
- SE_SESSION_QUEUE_PORT=5559
selenium-router:
image: selenium/router:4.0.0-rc-1-prerelease-20210618
container_name: selenium-router
ports:
- "4444:4444"
depends_on:
- selenium-distributor
- selenium-sessions
- selenium-session-queue
environment:
- SE_DISTRIBUTOR_HOST=selenium-distributor
- SE_DISTRIBUTOR_PORT=5553
- SE_SESSIONS_MAP_HOST=selenium-sessions
- SE_SESSIONS_MAP_PORT=5556
- SE_SESSION_QUEUE_HOST=selenium-session-queue
- SE_SESSION_QUEUE_PORT=5559
chrome1:
image: selenium/node-chrome:4.0.0-rc-1-prerelease-20210618
volumes:
- /dev/shm:/dev/shm
depends_on:
- selenium-event-bus
environment:
- SE_EVENT_BUS_HOST=selenium-event-bus
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=5
- SE_NODE_OVERRIDE_MAX_SESSIONS=true
- SCREEN_HEIGHT=900
- SCREEN_WIDTH=1600
ports:
- "5901:5900"
- "7901:7900"
chrome2:
image: selenium/node-chrome:4.0.0-rc-1-prerelease-20210618
volumes:
- /dev/shm:/dev/shm
depends_on:
- selenium-event-bus
environment:
- SE_EVENT_BUS_HOST=selenium-event-bus
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=5
- SE_NODE_OVERRIDE_MAX_SESSIONS=true
- SCREEN_HEIGHT=900
- SCREEN_WIDTH=1600
ports:
- "5902:5900"
- "7902:7900"
edge1:
image: selenium/node-edge:4.0.0-rc-1-prerelease-20210618
volumes:
- /dev/shm:/dev/shm
depends_on:
- selenium-event-bus
environment:
- SE_EVENT_BUS_HOST=selenium-event-bus
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
ports:
- "5903:5900"
- "7903:7900"
firefox1:
image: selenium/node-firefox:4.0.0-rc-1-prerelease-20210618
volumes:
- /dev/shm:/dev/shm
depends_on:
- selenium-event-bus
environment:
- SE_EVENT_BUS_HOST=selenium-event-bus
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=5
- SE_NODE_OVERRIDE_MAX_SESSIONS=true
- SCREEN_HEIGHT=900
- SCREEN_WIDTH=1600
ports:
- "5904:5900"
- "7904:7900"
第四部:生成测试环境
docker-compose -f docker-compose-v3-full-grid.yml up -d
docker-compose -f docker-compose-v3-full-grid.yml down
docker rm -f $(docker ps -qa)
运行测试
如下是一个selenium测试脚本,只需要你的机器装了Python3 并且安装了selenium 将代码中ip 和port替换成你安装Grid的主机ip 和Router 容器端口
import time
start_time = time.time()
from selenium import webdriver
ip = "xxx.xxx.xxx.xxx"
port = "4444"
node_chrome_capabilities=webdriver.DesiredCapabilities.CHROME.copy()
node_chrome_capabilities["browserName"] = "chrome"
node_chrome_capabilities["version"] = ""
node_chrome_capabilities["platform"] = "ANY"
node_chrome_capabilities["javascriptEnabled"] = True
node_chrome_capabilities["acceptInsecureCerts"] = True
browser = webdriver.Remote("http://%s:%s/wd/hub"%(ip,port), desired_capabilities=node_chrome_capabilities)
browser.get("https://www.163.com")
time.sleep(20)
print(browser.current_url)
browser.get_screenshot_as_file(r"D:/sample/chrome.png")
browser.quit()
end_time = time.time()
cost = end_time-start_time
print("time cost:%d"%int(cost))
浏览器访问 Grid主机ip:7901 和 Grid主机ip:7902 输入secret密码就能找到浏览器窗口,两个容器中必有一个。 如果找不到,说明跑完了。
负载均衡和排队
负载均衡就是新来的测试任务会运行在集群中压力最小的那台机器上。 我们的Node容器都是用cpu中的一个core处理的,假如服务器cpu有64核,理论上能开60个Node容器。 官方文档建议一个Node容器只运行一个浏览器测试任务,启动一个窗口。
登录 Grid主机ip:4444 能看到所有Node容器和测试任务的session情况。 如果你同时运行两遍这个脚本,它一定会运行在两个容器上,而不是同时运行在一个容器上。你可以修改yaml开多个Node容器并运行多个脚本,看看负载均衡的效果。 如下是3个job运行在3个Chrome的案例。
排队
上图中我有4个Chrome容器,每个容器做多同时并行5个job,即我能同时测20个任务。如果来了21个呢?最后来的那个会一直等待知道有一个任务结束了。
使用本地文件
如果测试过程中需要读本地文件怎么办? 原来本地化测试直接给个路径就能读到文件,现在缺搬到了容器里了。 在yaml文件中的Node配置中有一行: - /dev/shm:/dev/shm 这个就是宿主机和容器的共享文件夹,只要将待测文件放到宿主机的/dev/shm中,不管job运行在哪个容器里,都能读到和改写文件,这种共享文件夹叫数据卷,属于docker的功能。
今天就分享到这里,Bye!
|