原文转载自「刘悦的技术博客」https://v3u.cn/a_id_195

“世界上有那么多城市,城市里有那么多的酒馆,可她,却偏偏走进了我的…”,这是电影《卡萨布拉卡》中的一句著名独白,投射到现实生活中,与之类似的情况不胜枚举,这世界上有那么多的系统,系统中有那么多的浏览器,在只有一台测试机的前提下,难道我们只能排队一个一个地做兼容性测试吗?有没有效率更高的方法呢?为此我们提出一个更高效的解决方案:使用Docker+Selenium Grid。

Selenium Grid是一个分布式WebUI测试工具,可以将测试流程分发到多台服务器上,并行地执行。Selenium Grid架构中包含两个主要角色:Hub是中心点控制节点,而Node是Selenium的工作节点,它们注册到Hub上,并会操作浏览器执行由Hub下发的自动测试用例。

也就是利用一个调度中心,分别在不同机器上安装不同的操作系统,系统中再安装对应需要测试的浏览器,但是,以传统的方式部署分布式Selenium Grid集群有一定的技术难度。而且一个浏览器在操作系统上只能安装一个版本且只能有一个运行实例。比如为了针对不同版本的Chrome进行测试,需要将指定版本的Chrome浏览器安装到不同物理机或虚拟机上,这样要耗费大量时间和机器成本来准备测试环境。

怎么简化Selenium Grid集群安装过程中的复杂性呢?答案是Docker,是的,Docker,又见Docker,Docker可以在单台服务器上利用容器技术直接部署多个节点,过程简单方便,只需要编写Dockerfile脚本即可,大大提升了测试效率,本次我们就使用Docker+Selenium Grid来实现多系统多版本浏览器并发式兼容性测试。

首先,安装Docker,请移步:win10系统下把玩折腾DockerToolBox以及更换国内镜像源(各种神坑)

随后,拉取Selenium Grid调度中心的镜像文件:

docker pull selenium/hub

这里我们测试两款不同的浏览器兼容性:Chrome、FireFox

所以分别拉取镜像文件:

docker pull selenium/node-chrome
docker pull selenium/node-firefox

全部三个镜像下载成功后,输入命令:

docker images

查看本地镜像:

liuyue:mytornado liuyue$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
selenium/node-chrome latest 0843e55de3dc 2 weeks ago 1.04GB
selenium/hub latest 705be32777f0 2 weeks ago 283MB
selenium/node-firefox latest f794497d8393 2 months ago 956MB

检查没有问题后,我们来编写Docker-compose的配置文件,Docker-compose是最基本的容器编排工具,它可以快速统筹多个镜像的协同使用,编写docker-compose.yml:

version: "3"
services: hub:
image: selenium/hub
ports:
- "4444:4444" environment:
GRID_MAX_SESSION: 16
GRID_BROWSER_TIMEOUT: 3000
GRID_TIMEOUT: 3000 chrome:
image: selenium/node-chrome
container_name: chrome
depends_on:
- hub
environment:
HUB_PORT_4444_TCP_ADDR: hub
HUB_PORT_4444_TCP_PORT: 4444
NODE_MAX_SESSION: 4
NODE_MAX_INSTANCES: 4
volumes:
- /dev/shm:/dev/shm
ports:
- "9001:5900"
links:
- hub firefox:
image: selenium/node-firefox
container_name: firefox
depends_on:
- hub
environment:
HUB_PORT_4444_TCP_ADDR: hub
HUB_PORT_4444_TCP_PORT: 4444
NODE_MAX_SESSION: 2
NODE_MAX_INSTANCES: 2
volumes:
- /dev/shm:/dev/shm
ports:
- "9002:5900"
links:
- hub

配置文件的主要内容就是将Selenium Grid的容器服务hub部署在4444端口上,并且通过端口映射,让宿主机可以访问,使用镜像就是我们刚刚下载好的selenium/hub镜像,而火狐(firefox)和谷歌(chrome)这两款浏览器分别依赖于hub服务,NODE_MAX_INSTANCES定义了可以运行多少个浏览器实例。

此时,我们在docker-compose.yml所在的目录执行命令,来启动服务:

docker-compose -f docker-compose.yml up -d

-d 参数意味着在后台运行,当然了您也可以选择在前台运行。

随后访问浏览器 http://localhost:4444/grid/console ,这里请求的ip是宿主机本地的,但其实是通过端口映射访问docker容器内的Selenium Grid调度中心:

可以看到,两款浏览器的服务都已经正常启动,分别运行四个和两个实例,同时也可以在终端运行Docker命令来查看进程:

docker ps

返回容器列表:

liuyue:mytornado liuyue$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
adcd4683f39c selenium/node-firefox "/opt/bin/entry_poin…" 2 days ago Up 2 days 0.0.0.0:9002->5900/tcp firefox
58dfe5825439 selenium/node-chrome "/opt/bin/entry_poin…" 2 days ago Up 2 days 0.0.0.0:9001->5900/tcp chrome
97d602944b34 selenium/hub "/opt/bin/entry_poin…" 2 days ago Up 2 days 0.0.0.0:4444->4444/tcp mytornado_hub_1

浏览器准备好了,接下来的事情就简单了,让我们来用Docker容器实际测试一下,编写test.py:

import time
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities #指定运行主机与端口号
driver = webdriver.Remote(command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME) driver.get("https://v3u.cn") time.sleep(1) driver.get_screenshot_as_file("v3u.png") driver.close()

这里使用chrome浏览器驱动使用远程模式(Remote),访问宿主机本地ip,端口4444,打开本站之后,截图查看是否有布局错误问题。

查看截图:

再来试试火狐浏览器(firefox):

import time
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities #指定运行主机与端口号
driver = webdriver.Remote(command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities=DesiredCapabilities.FIREFOX) driver.get("https://v3u.cn") time.sleep(1) driver.get_screenshot_as_file("v3u_frefox.png") driver.close()

查看firefox下的测试截图:

差别不大,但是可以通过实际测试看出细节的差异,比如字体和超链接颜色的不同,这些都是兼容性测试中的常备部分。

诚然,我们完全可以将代码写得更加规范一些,毕竟,这是在做兼容性测试,谁也不想在测试工作中出现任何的纰漏,这里使用Python内置的单元测试库unittest将之前的代码重构一下:

`import os
import datetime
import time
import unittest
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities class Example(unittest.TestCase): def setUp(self): self.driver = webdriver.Remote(
command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME)` `self.driver.get("https://v3u.cn") def test_firefox(self): time.sleep(1) self.driver.get_screenshot_as_file("v3u_chrome.png") def tearDown(self): self.driver.quit() if __name__ == "__main__": unittest.main(verbosity=1)`

测试结果:

liuyue:pickupname liuyue$ python3 "/Users/liuyue/Downloads/ccpt_21_cvm/鼠标/pickupname/test.py"
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/remote_connection.py:374: ResourceWarning: unclosed <socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('127.0.0.1', 63563), raddr=('127.0.0.1', 4444)>
return self._request(command_info[0], url, body=data)
ResourceWarning: Enable tracemalloc to get the object allocation traceback
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/remote_connection.py:374: ResourceWarning: unclosed <socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('127.0.0.1', 63566), raddr=('127.0.0.1', 4444)>
return self._request(command_info[0], url, body=data)
ResourceWarning: Enable tracemalloc to get the object allocation traceback
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/remote_connection.py:374: ResourceWarning: unclosed <socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('127.0.0.1', 63573), raddr=('127.0.0.1', 4444)>
return self._request(command_info[0], url, body=data)
ResourceWarning: Enable tracemalloc to get the object allocation traceback
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/remote_connection.py:374: ResourceWarning: unclosed <socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('127.0.0.1', 63574), raddr=('127.0.0.1', 4444)>
return self._request(command_info[0], url, body=data)
ResourceWarning: Enable tracemalloc to get the object allocation traceback
.
----------------------------------------------------------------------
Ran 1 test in 5.908s OK

测试完毕后,可以通过Docker-compose命令一键停止容器服务,非常方便:

docker-compose -f docker-compose.yml down

尤其是容器数量非常多的情况下,我们不需要手动一个一个来停止服务:

liuyue:mytornado liuyue$ docker-compose -f docker-compose.yml down
Stopping firefox ... done
Stopping chrome ... done
Stopping mytornado_hub_1 ... done
Removing firefox ... done
Removing chrome ... done
Removing mytornado_hub_1 ... done
Removing network mytornado_default
liuyue:mytornado liuyue$

再次查看服务进程:

liuyue:mytornado liuyue$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
liuyue:mytornado liuyue$

结语:本次,我们介绍了分布式自动化Web测试软件Selenium Grid的设置、服务的运行、以及停止,没有任何问题。通过使用这种自动化测试方法,我们可以节省大量时间,并以高效的方式获得最准确的测试结果。如果您现有测试机的配置更加优秀,还可以进一步探索,尽可能多的开启浏览器实例,以此做到海量并发兼容性测试。

原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_195

浩若烟海事半功倍|利用Docker容器技术构建自动化分布式web测试集群Selenium Grid的更多相关文章

  1. docker-compose 快速部署Prometheus,监控docker 容器, 宿主机,ceph -- cluster集群

    话不多说上菜: 现在环境是这样: ceph 4台: 192.168.100.21  ceph-node1 192.168.100.22  ceph-node2 192.168.100.23  ceph ...

  2. 使用 Docker, 7 个命令部署一个 Mesos 集群

    这个教程将给你展示怎样使用 Docker 容器提供一个单节点的 Mesos 集群(未来的一篇文章将展示怎样很容易的扩展这个到多个节点或者是见底部更新).这意味着你可以使用 7 个命令启动整个集群!不需 ...

  3. Swarm 如何存储数据?- 每天5分钟玩转 Docker 容器技术(103)

    service 的容器副本会 scale up/down,会 failover,会在不同的主机上创建和销毁,这就引出一个问题,如果 service 有要管理的数据,那么这些数据应该如何存放呢? 选项一 ...

  4. 当公有云Azure拥抱Docker容器技术

    本文转载至 http://3387405.blog.51cto.com/3377405/1598977 预见未来看似是一件不太可能的事情,然而现在企业科技高速发展的态势完全超乎想象. 就在几周前Inf ...

  5. docker-每天5分钟玩转Docker容器技术

    安装 https://www.cnblogs.com/qinxu/p/10032176.html 安装教程,目前只能安装到18版本的,安装完后执行下面命令更新到版本19 yum install doc ...

  6. 一文了解Docker容器技术的操作

    一文了解Docker容器技术的操作 前言一.Docker是什么二.Docker的安装及测试Docker的安装Docker的Hello world测试三.Docker的常见操作镜像的基本操作容器的基本操 ...

  7. 三文搞懂学会Docker容器技术(下)

    接着上面一篇:三文搞懂学会Docker容器技术(上) 三文搞懂学会Docker容器技术(中) 7,Docker容器目录挂载 7.1 简介 容器目录挂载: 我们可以在创建容器的时候,将宿主机的目录与容器 ...

  8. 【Docker】(9)---每天5分钟玩转 Docker 容器技术之镜像

    镜像是 Docker 容器的基石,容器是镜像的运行实例,有了镜像才能启动容器.为什么我们要讨论镜像的内部结构? 如果只是使用镜像,当然不需要了解,直接通过 docker 命令下载和运行就可以了. 但如 ...

  9. 微服务架构:基于微服务和Docker容器技术的PaaS云平台架构设计(微服务架构实施原理)

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 基于微服务架构和Docker容器技术的PaaS云平台建设目标是给我们的开发人员提供一套服务快速开发.部署.运维管理.持续开发持续集成的流程 ...

随机推荐

  1. 解决mysq服务无法正常启动问题

    在mysql的启动过程中,遇到什么问题都可以反馈给我,我都会尽力帮你们解决 第一种:通过net start mysql启动MySQL服务器时,出现以下信息 是因为在MySQL5.7以上的版本中默认的没 ...

  2. SM3和Blake

    在此给出SM3和Blake的对比 哈希函数 哈希算法 (Hash Algorithm) 是将任意长度的数据映射为固定长度数据的算法,也称为消息摘要.一般情况下,哈希算法有两个特点, 一是原始数据的细微 ...

  3. 08shell脚本

    shell脚本编程 1.1简介 什么是shell脚本 shell脚本: 就是一些命令的集合, 在脚本文件中可以有流程控制, 如顺序, 条件分支和循环等 脚本文件一般一.sh文件为扩展名, 但是不是必须 ...

  4. 关于『进击的Markdown』:第四弹

    关于『进击的Markdown』:第四弹 建议缩放90%食用 美人鱼(Mermaid)悄悄的来,又悄悄的走,挥一挥匕首,不留一个活口 又是漫漫画图路... 女士们先生们,大家好!  我们要接受Markd ...

  5. 遍历list集合泛型为map

    public class ListAddMap { public static void main( String args[] ) { List<Map<String, Object&g ...

  6. React设置proxy后依旧报CROS错误

    1.判断表单数据是否为后端接收的类型 POST GET2.axios自动转换问题 手动添加标头这份表单数据包括了files (二进制数据)而标头显示是JSON格式 不符 所以报CROS 更多文章请移步 ...

  7. 使用 Nocalhost 开发 Rainbond 上的微服务应用

    本文将介绍如何使用 Nocalhost 快速开发 Rainbond 上的微服务应用的开发流程以及实践操作步骤. Nocalhost 可以直接在 Kubernetes 中开发应用,Rainbond 可以 ...

  8. redis客户端打不开 提示cannot connect to server dev.check log for details

    我当前状况是redis客户端打不开,之前一直好好的(虽然作为一个程序员我不配说这句话,哈哈),但是我排查了我觉得所有的可能性,我用的阿里云的redis(还没有到购买到期时间),然后我就关闭了防火墙,你 ...

  9. C语言- 基础数据结构和算法 - 队列的顺序存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  10. PowerShell 定时刷新查看文件内容

    get-content .\1.txt -ReadCount 0 -Tail 5 -Wait