背景

项目 UI 自动化测试使用的是 Robot Framework + SeleniumLibrary 框架,由于 RF 脚本逐渐积累,跑一次需要的时间比较长,需要使用 Selenium Grid 分布式执行来缩短测试时间,采用了 docker 来构建 Selenium Grid。过程中遇到了一些坑,这里跟同学们分享一下。

环境

如何使用 Docker 搭建 Selenium Grid 环境这里就不多说了,社区也有一些同学写了分享帖。下面是项目运行环境:

执行 RF 脚本时浏览器崩溃

最开始是在命令行执行以下命令来构建 Selenium Grid:
docker run -p 4444:4444 -d --name hub selenium/hub:3.14.0
docker run -p 5900:5900 -d --name ff1 --link hub:hub selenium/node-firefox-debug:3.14.0
docker run -p 5901:5900 -d --name ff2 --link hub:hub selenium/node-firefox-debug:3.14.0

但是脚本刚跑没多久浏览器就崩溃了:A content process crashed and MOZ_CRASHREPORTER_SHUTDOWN is set, shutting down。原因是容器分配的内存不够用,需要将容器的虚拟内存目录挂载到宿主机的虚拟内存目录:
docker run -p 5900:5900 -d-v /dev/shm:/dev/shm--name ff1 --link hub:hub selenium/node-firefox-debug:3.14.0

docker-compose 构建 Selenium Grid 时挂载容器目录失败

上面跑通脚本之后,使用 docker-compose 构建 Selenium Grid,脚本如下:

version: "3"
services:
  selenium-hub:
    image: selenium/hub:3.14.0
    container_name: selenium-hub
    ports:
      - "5555:4444"

  firefox1:
    image: selenium/node-firefox-debug:3.14.0
    container_name: ff1
    volumes:
      - "/dev/shm:/dev/shm"
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444
      - SCREEN_WIDTH=1920
      - SCREEN_HEIGHT=1080
    ports:
      - "5910:5900"

  firefox2:
    image: selenium/node-firefox-debug:3.14.0
    container_name: ff2
    volumes:
      - "/dev/shm:/dev/shm"
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444
      - SCREEN_WIDTH=1920
      - SCREEN_HEIGHT=1080
    ports:
      - "5911:5900"

但是 docker-compose 启动容器时,挂载容器虚拟内存目录失败,报错如下:
ERROR: for ff1 Cannot create container for service firefox1: b'Mount denied:\nThe source path "\\\\dev\\\\shm:/dev/shm"\nis not a valid Windows path'
这是一个 bug,见https://github.com/docker/for-win/issues/1829 解决方法是在系统变量中加上 COMPOSE_CONVERT_WINDOWS_PATHS=1

Selenium Grid 使用多个节点执行时,浏览器页面加载变慢

开一个 Firefox 节点执行的时候,RF 脚本可以跑得很顺畅,但是加到 2 个节点以上时,可以通过 VNC viewer 看到页面加载很慢,导致很多脚本失败。
猜测还是由于内存不足导致,监控执行 RF 脚本时 Selenium Grid 节点的资源消耗,发现使用 Firefox profile 打开浏览器的节点使用内存大大增加。启动 Selenium Grid 时虽然把 Firefox 节点的虚拟内存目录挂载到了宿主机,但这个宿主机实际上是 Linux 虚拟机,并不是 Win10 机器,Win10 默认给 docker 宿主机分配的内存是 2G,SeleniumGrid 启动一个 Firefox 节点执行时,内存正好够用,增加到两个节点时,内存已经达到 Linux 虚拟机的上限了,导致浏览器页面加载变慢甚至崩溃。
下图为两个 Firefox 节点并行行执行 RF 脚本,没有使用 Firefox profile 时的资源使用情况,Selenium Grid 占用大概 1G 内存

下图为两个 Firefox 节点并行执行 RF 脚本,使用 Firefox profile 时的资源使用情况,Selenium Grid 占用大概 3G 内存。

为什么要使用 Firefox profile:Selenium 每次打开的浏览器是纯净的,但是有些 RF 脚本需要使用 Firefox 的一些自定义配置,因此启动浏览器时要指定 Firefox profile。

两次跑的 case 是一样的,区别仅在与有没有使用 Firefox profile,但是不知道为什么内存消耗为啥会增加这么多?技术有限,没有继续挖掘,但是这个问题限制了 Docker + Selenium Grid 分布式执行 Selenium 脚本的能力,当然,如果你不需要用到 Firefox profile 会好一些。目前项目只有这一台 Win 10 机器是专门跑自动化测试脚本的,内存只有 8G,Selenium Grid 开 10 个节点的梦想破灭😂

目前只能把 docker 宿主机的内存调高一点,暂时解决这个问题。如下图所示,把内存调到了 4G,两个 Firefox 节点并行跑 RF 脚本,目前没有出现其他问题。


↙↙↙阅读原文可查看相关链接,并与作者交流