Selenium Docker 在 WebUI 自动化测试中的应用

Baozhida · 2017年04月28日 · 最后由 远行者 回复于 2018年09月04日 · 6088 次阅读

转自途牛公共号

本文主要介绍通过 Docker 简化 Selenium Grid 分布式测试的部署,缓解分布式自动化测试的痛点问题。

相对于官方镜像,主要特点是支持老版本浏览器

一、知识储备

1、Selenium 基础

Selenium

是针对Web应用的自动化测试框架和工具集合;
支持多种浏览器和编程语言;
测试用例直接运行在浏览器中,并模拟用户的操作。

Selenium Grid

是一种可以进行分布式自动化测试的辅助工具,该架构中包含两个主要角色:
Hub是中心点控制节点;
Node是Selenium的工作节点,它们注册到Hub上,并会操作浏览器执行由Hub下发的自动测试用例。

web 端的自动化测试呈现一家独大的状态,大部分都在使用 selenium 完成,也是各大浏览器官方支持的工具,应用非常普遍。

以传统的方式部署分布式 Selenium Grid 集群需要耗费大量时间和机器成本来准备测试环境。比如为了针对不同版本的 Chrome 进行测试,需要将指定版本的 Chrome 浏览器安装到不同物理机或虚拟机上。

2、Docker 基础

Docker 是开源的应用容器引擎,让开发者可以打包应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。主要有三个组件:

  • 容器 container

容器是镜像创建的实例,是应用实际运行的位置。

  • 镜像 image

一个镜像可以包含一个完整的操作系统环境和用户需要的其它应用程序。docker 的镜像是只可读的,一个镜像可以创建多个容器。

  • 仓库 repository

仓库是集中存放镜像的系统。hub.docker.com 是 docker 官方的公开仓库,存放了大量的镜像供用户下载。

3、Selenium 和 Docker 怎么结合使用?

目前可以把版本最多,更新最频繁的 Chrome 浏览器环境和 Firefox 浏览器环境部署在 Docker 容器中。

4、Selenium 官方镜像

selenium 官方其实已经支持了 docker 搭建镜像环境,镜像仓库地址:
https://hub.docker.com/r/selenium/

Docker 仓库允许关联 Github 仓库自动构建镜像。
构建镜像所需的 Dockerfile 来自 Github:
https://github.com/SeleniumHQ/docker-selenium

官方镜像存在两点问题:
(1)系统字体不支持中文,中文网站乱码;
(2)官方的镜像默认使用最新的稳定版,chrome 现在是 V58,没有老版本的镜像。
为了解决这两个问题,需要自己创建镜像。

二、创建镜像

1.修改 Dockerfile

改版之后的 DockerFile 地址
https://github.com/baozhida/docker-selenium

Dockerfile 文件主要安装的部件有:
ubuntu16.04
java8
selenium jar包
browser(chrome和firefox)
driver(chromedriver和geckodriver)
VNCServer
一些可执行脚本等

新的浏览器镜像仓库地址:https://hub.docker.com/u/baozhida/

新增的镜像:

Chrome 浏览器镜像 V48-V58:

Firefox 浏览器镜像 V47-V52:

三、创建容器

1.安装使用 Docker Toolbox

(1)由于 Docker 不能在 Windows7 不能直接安装使用,但可以借助 Toolbox 来完成。
安装步骤的截图:

主要包含以下一些内容:

  • DockerClient 客户端
    用来运行 docker 引擎创建镜像和容器

  • DockerMachine
    在 windows 的命令行中运行 docker 引擎命令

  • DockerCompose
    用来运行 docker-compose 命令

  • Virtualbox

  • Kitematic
    这是 Docker 的 GUI 版

  • Git

说明:
Docker 支持 Windows Server、Windows 10、Mac OS 和其它 Linux 内核的系统;
DockerToolbox 其实是一个针对不能直接使用 docker 的系统定制的 Docker 工具包,集成了多种工具。

(2)安装之后桌面生成三个快捷方式。点击 DockerQuickstartTerminal 图片启动 docker,Windows7 上默认 ip 是 192.168.99.100。

启动成功,终端展示的信息:

打开 VirtualBox 虚拟机:

说明:
default 默认内存 1G,可以改大来适应并发测试;
default 虚拟机默认使用 Host-Only 网络,所以只能本机连接,不使用 DockerToolbox,直接安装 Docker 的环境,没有这个限制。

(3)后面的操作大部分都在 default 虚拟机里面完成,所以可以使用传统的远程工具进行命令行操作,比如 Xshell
用户名:docker
密码:tcuser
IP:192.168.99.100
端口:22

2.下载镜像

命令 docker pull:从 docker hub 中下载镜像。
以 hub 和 4 个 node(chromev48、chromev58、firefox47、firefox52)节点为例:

下载的命令是 docker pull+ 镜像名称 +tag

docker pull baozhida/selenium-hub:3.3.1
docker pull baozhida/selenium-node-chrome-debug:48
docker pull baozhida/selenium-node-chrome-debug:58
docker pull baozhida/selenium-node-firefox-debug:47
docker pull baozhida/selenium-node-firefox-debug:52

说明:
默认的 tag 是 latest;
dockerhub 服务器在海外,所以网速时好时坏,有时还会 timeout 报错,多试几次一定能成功。

3.创建并运行容器

分别为上面下载的镜像创建并运行容器
创建 selenium hub 容器
docker run -d -p 4444:4444 --name selehub baozhida/selenium-hub:3.3.1

创建 chrome node 容器
docker run -d -p 5911:5900 --name node48 --link selehub:hub --shm-size=512m baozhida/selenium-node-chrome-debug:48

docker run -d -p 5901:5900 --name node58 --link selehub:hub --shm-size=512m baozhida/selenium-node-chrome-debug:58

创建 firefox node 容器
docker run -d -p 5917:5900 --name ff47 --link selehub:hub --shm-size=512mbaozhida/selenium-node-firefox-debug:47

docker run -d -p 5912:5900 --name ff52 --link selehub:hub --shm-size=512m baozhida/selenium-node-firefox-debug:52

说明:
*-d 参数:后台模式运行;

--name 参数:别名;

-p 参数:将容器的 5900 端口映射到 docker 的 5901 端口,访问 Docker 的 5901 端口即可访问到 node 容器;

--shm-size 参数:docker 默认的共享内存/dev/shm 只有 64m,有时导致 chrome 崩溃,该参数增加共享内存大小到 512m.*

4.查看镜像和容器

命令 docker images:查看本地已经下载的镜像

docker ps -a 查看正在运行的容器:

在浏览器输入地址http://192.168.99.100:4444/grid/console
查看 Selenium Grid 控制台,能看到刚创建的容器已经正常注册。

5.VNC 远程浏览器环境

debug 结尾的镜像都带有 VNC 服务端,本机安装 VNC 客户端,即可远程连接。

已 chrome58 的容器为例:
输入 192.168.99.100:5901-->回车-->输入密码:secret-->确认-->进入容器桌面

6.远程桌面检查

三条命令检查创建的镜像是否正常:
chromedriver -v :查看驱动的版本
google-chrome --version :查看浏览器版本
google-chrome :直接启动浏览器

四、编码实现 UI 测试

1.Driver 初始化 (JAVA)

初始化的代码摘要如下:
(1)指定 chrome,版本随机

WebDriverdriver = new RemoteWebDriver(new URL(http://192.168.99.100:4444/wd/hub/”),DesiredCapabilities.chrome());

(2)指定 chrome 版本

DesiredCapabilitiesdesiredCaps=new DesiredCapabilities(chrome, 48.0.2564.109, Platform.LINUX); 
WebDriverdriver = new RemoteWebDriver(new URL(http://192.168.99.100:4444/wd/hub/”),desiredCaps);

(3)指定 firefox,版本随机

WebDriverdriver = newRemoteWebDriver(new URL(http://192.168.99.100:4444/wd/hub/”),    DesiredCapabilities.firefox());

(4)指定 firefox 版本

DesiredCapabilitiesdesiredCaps= new DesiredCapabilities(firefox, 47.0, Platform.LINUX); 
WebDriverdriver = newRemoteWebDriver(new URL(http://192.168.99.100:4444/wd/hub/”),desiredCaps);

2.并发执行

TestNG 是支持多线程测试框架,对分布式的 UI 自动化测试有着较好的支持。和 ant 和 Jenkins 结合可以搭建持续集成环境。

Demo 项目:https://github.com/baozhida/uiauto
项目中的配置文件 testng.xml,配置四个容器浏览器信息,线程设置为 4,部分截图如下:

执行 TestNG,四个容器中的浏览器同时打开浏览器,并执行测试脚本。

3.测试报告

TestNG 结合 ANT 和 ReportNG 自动生成测试报告:

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 31 条回复 时间 点赞
  1. 乱码不是因为系统编码问题,是因为系统没有安装对应的字体。毕竟镜像是老外做的,没有中文的那些字体是比较正常的。你可以继承它的镜像做自己的定制,安装你想要的字体,例如我装的是微软的雅黑字体。如下是我做的:

    另外不要一个节点只启动一个浏览器,那样很浪费资源。传递环境变量进去可以改变配置。如下:

    1. chrome node 的镜像有很多版本的。像我用的是 3.2.0。 你可以去 github 和 docker hub 上查看一下信息

另外你也可以用像 1 中的方法。自己定制一个镜像,把 chrome 的版本换了

孙高飞 回复

是我理解不深,解决乱码,就是安装了中文字体,在 Dockerfile 文件里完成的

已更新

再加上 jenkins 就完美了

tonybearpan 回复

Ant 执行文件都写好了,jenkins 配置一下就好了

Baozhida 回复

我的意思是 jenkins 放进 docker

孙高飞 回复

另外不要一个节点只启动一个浏览器,那样很浪费资源。传递环境变量进去可以改变配置。

这里能说的详细点吗?

像图里的一样, 可以设置 session 和实例的数量。 其实你进入到容器里。看一下环境变量你就会发现有很多可以设置的东西。 包括 java 的启动参数

孙高飞 回复

一个容器这么多实例,有两个疑问
1,多个实例一起运行,稳定么,我没试过
2,是执行一样的,还是每个浏览器执行不同的用例,怎么控制的

我用的是单实例,官网的例子也是单实例

# As integer, maps to "maxInstances" 
ENV NODE_MAX_INSTANCES 1 
# As integer, maps to "maxSession" 
ENV NODE_MAX_SESSION 1
Baozhida 回复
  1. 还是比较稳定的,我现在一直这么用
  2. 每个浏览器跑不同的用例。 很简单。 用 testng 的并发执行就行,把 case 分成一个个的组

楼主请问下,我如果要改容器里的 host 可以吗?他没有 vi 编辑命令。。不改 host 配置无法访问测试环境。。

孙高飞 回复

如何使用 selenide,testng 并发,当我设置容器 session=5,然我 testng 设置,
这样 4 个 test,看了下容器还是只启动一个浏览器.

我搜了下,有人这样解决String urlToRemoteWD = "http://some.url.to.remote/wd/hub";
RemoteWebDriver driver =new RemoteWebDriver(new URL(urlToRemoteWD),DesiredCapabilities.firefox());
WebDriverRunner.setWebDriver(driver);


请问下你是怎么样设置并发的,selenide 支持还是要使用 selenium

白纸 回复

你去 hub 上看一下是不是有 5 个浏览器准备着

孙高飞 回复

有 5 个的

白纸 回复


这两个参数都设置为 5 了么?

白纸 回复


而且 testng 的配置文件要这么写

孙高飞 回复

docker run -d -p 5999:5900 --link hub:hub --name chromes -e NODE_MAX_INSTANCES=5 -e NODE_MAX_SESSION=5 -e NODE_REGISTER_CYCLE=5000 -e DBUS_SESSION_BUS_ADDRESS=/dev/null selenium/node-chrome-debug
这样起的

这样配置的 xml

白纸 回复

你这配置的就是顺序执行啊, 不是并发。 一个 test 一个线程,你那 3 个 test 里没 case 吧

孙高飞 回复

有 case 只是太多 隐藏了,...要把preserve-order="true" 去掉,? 这个不是设置 test 里面的 class 顺序执行吗

白纸 回复


selenide 里的 remote 是这么设置的么

孙高飞 回复


这样设置的,然后每个 testcase 类里面一个

白纸 回复

我发现了。。。。你拼错了😂
是 parallel

孙高飞 回复

😔 少了个 a......😂

孙高飞 回复

活捉一次,再问个问题。。。我是用 docker-comp run -d,hub 起来了,chrome 起了立刻就关了

hub:
container_name: hub
image: selenium/hub
ports:
-"5554:4444"
registry:
container_name: chrometest
environment:
DBUS_SESSION_BUS_ADDRESS: /dev/null
NODE_MAX_INSTANCES: 5
NODE_MAX_SESSION: 5
NODE_REGISTER_CYCLE: 5000
image: test/chrome
links:
-hub
ports:
-"5901:5900"
volumes:
-"dev/shm:/dev/shm"

孙高飞 回复

大神,请问您解决了并发,而不是 testng.xml 中的顺序执行?

cooling 回复

不是顺序执行,就是并行的

为何,在 VNc 中打开后,不是界面显示不是同时执行 case?还有就是 docker _maven _运行时间比本地长了三倍,是虚拟机内存,网络的关系?

Baozhida 回复

请问还有不有其他的 docker——selenium_hub 镜像元?

楼主,请教个问题,为何,我 testng.xml 中用的 classes,用 mvn test 能成功执行脚本。但是 testng.xml 中 suite 中,换成 tests,mvn test 就失败,百思不解,请指导,谢谢

—— 来自 TesterHome 官方 安卓客户端

如果有多个相同版本的浏览器如何指定浏览器运行呢?
能否通过指定 host 运行呢?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册