Selenium 结合 Docker-Selenium 镜像进行 Web 应用并发自动化测试

terrychow · 2017年03月29日 · 最后由 terrychow 回复于 2017年08月15日 · 6831 次阅读
本帖已被设为精华帖!

一、前言

  • 最近一直在还去年的技术债,去年我们测试团队投入一大堆测试技术,但没有多少个是做精的,那今年的目标就是做到极致,去年团队落地了 Web 和移动端的自动化测试,但随着用例的增加,执行自动化脚本的时间越来越长,我们还需要做快速迭代的,很多时候一天还可能发几个版来响应客户的需求,那面对频繁地发版。自动化测试的支撑就应更加高效,所以就想到落地并发自动化测试来提高自动化测试的执行效率,但对于 web 应用,一台机器上跑多个浏览器的时候,对于业务交互时也比较麻烦,而且一种浏览器在一台机器上一般只有一个,那要做并发就要多台机器,问题在没有那么多资源的情况下要怎么做,正好最近翻其他技术网站的时候翻到Docker-selenium,通过 selenium gird+docker 容器很好地把多台分布式容器利用起来,更充分的利用机器的资源,这样 web 的并发自动化测试就可以落地了,并解决了在多个浏览器跑兼容测试的难题

二、操作过程

  • 先说明一下具体的并发架构

  • 自动化具体执行的流程

第一步:docker-compose 自动构建浏览器测试环境容器
首先还是先看一下前言中的链接如何使用 selenium gird+docker,对于 selenium gird 的容器的启动,可以用 docker-compose.yml 做容器自动编排,这样就不用手工一步一步去启动容器和 link 了
具体的 docker-compose.yml 描述

docker-compose.yml
hub:
  image: lunkrtech.rd.mt/wqzhou/selenium-hub
  ports:
    - 4444:4444
firefox:
  image: lunkrtech.rd.mt/wqzhou/node-firefox-debug-zh
  ports:
    - 5901:5900
  links:
    - hub
chrome:
  image: lunkrtech.rd.mt/wqzhou/node-chrome-debug-zh
  ports:
    - 5902:5900
  links:
    - hub
chrome2:
  image: lunkrtech.rd.mt/wqzhou/node-chrome-debug-zh
  ports:
    - 5903:5900
  links:
    - hub

其中 hub 就是 selenium gird 的容器,启动的时候使用 4444 端口,其他的是浏览器的镜像,而且这里也说明一下浏览器容器的 5900 端口,在 docker.io 获取浏览器镜像时,会有 debug 版,debug 的话是可以通过 VNC Viewer 连接映射的端口来查看调试浏览器和用例的具体执行情况,一般也建议直接用 debug 版,上面分别用了 2 个 chrome 和 1 个 firefox 的容器集群构建成分布式的 web 自动化测试环境
启动完整之后打开 selenium gird,就能看到具体浏览器容器的启动情况,当然,这一步也是要做到自动检查是否启动成功的

第二步:并发框架设计

  • 并发的框架也是利用了 python 多线程的方法去实现的,其实具体的思想可以参考简单入手移动端并发自动化测试,不过比起这个当然是有改良的,之前用了 bat 脚本,这样执行的时候一旦并发多了总是弹窗口,显然就不好用了,后面就结合 robot 的 tag 来改良了并发框架
  • 首先是 robot 的测试用例或测试套件分别贴上 tags,代表分布在不同的容器上执行,其中 node1 和 node2 在远程容器中执行,所以要加上 remote_url,local 是指在本地执行,本地执行还是必要的,像一些上传本地文件的操作,放到远程机器上是执行不了的,所以保留本地执行
*** Settings ***
Library           Selenium2Library

*** Test Cases ***
open_baidu
    [Tags]    node1
    Open Browser    https://www.baidu.com    firefox    remote_url=http://lunkrtech.rd.mt:4444/wd/hub
    sleep    6
    [Teardown]    Close Browser

open_lunkr
    [Tags]    local
    Open Browser    https://www.lunkr.cn    chrome
    sleep    3
    Wait Until Page Contains Element    id=setting    3
    [Teardown]    Close Browser

open_coremail
    [Tags]    node2
    Open Browser    http://www.coremail.cn    chrome    remote_url=http://lunkrtech.rd.mt:4444/wd/hub
    sleep    6
    [Teardown]    Close Browser

tags 标记好用例之后,那就是并发框架的设计了,核心代码如下:

def run(arg):
   os.system(str(arg))

threads = []
testsuite=sys.argv[1]
tags=sys.argv[2]
taglist=tags.split(',')

for tag in taglist:
   cmd='pybot -i {0} -o .\\resultDir\\output-{0}.xml -l .\\resultDir\\log-{0}.html -r .\\resultDir\\report-{0}.html {1}'.format(tag,sys.argv[1]) 
   t= threading.Thread(target=run,args=(cmd,))
   threads.append(t)

-------这里省略产生多线程的代码-----------

os.system(u"rebot --output .\\resultDir\\output.xml  -l .\\resultDir\\log.html -r .\\resultDir\\report.html --merge .\\resultDir\\output-*.xml")

脚本 robot_mutil_dev.py 接收两个参数,第一个,执行的测试套件或文件夹,第二个,以逗号分隔的多个标签,然后有多少个标签,就启动多少个线程根据不同的标签执行 pybot -i tag 的命令,至于怎么使用 python 的多线程这里就不用多说了,大家估计比我还熟悉,最后所有自动化测试的线程都结束之后执行 rebot 的命令来合并自动化测试报告

三、执行过程演示

  • 具体的执行过程就是执行 python 脚本就好了,当然我们可以用 jenkins 来做自动构建触发自动化测试的执行,jenkins 的流程可参考之前写过的一篇


    其实就是执行robot_mutil_dev.py webmutil.txt local,node1,node2,webmutil.txt 是测试套件,后面的是刚才标记的 tags

  • 执行过程:

上面有 2 个浏览器就是通过 VNC viewer 来连接到容器中查看远程浏览器的情况的,在连接到 selenium gird 的时候,gird 会自动判断哪个浏览器是空闲的,那 gird 就会把用例分配到对应空闲的浏览器中执行

大概并发的自动化测试就实现了,当然这里还有一个注意的地方,就是执行用例失败之后的截图,如果是多线程执行的话,截图也是多线程的,线程 1 产生的截图 1 命名为 selenium-screen-1.png,线程 2 也会产生的截图 1 命名为 selenium-screen-1.png,那这样线程 2 的截图就会把线程 1 的截图给覆盖了,那解决办法是,既然用到线程,那肯定有线程或进程 id 的,那就在图片命名中加一个线程 id 号就能解决问题了,具体的就是在 selenium2library 中的_screenshot.py:

def _get_screenshot_paths(self, filename):
      if not filename:
          self._screenshot_index += 1
          pid=os.getpid()
          filename = 'selenium-%s-screenshot-%d.png' % (pid,self._screenshot_index)
      else:
          filename = filename.replace('/', os.sep)

那这样就万事大吉了,执行完测试之后具体生成的文件,在 jenkins 把对应路径配置好上传必须的文件就好了:

  • 最后一步当然是执行完成以后看到的测试报告


    也可以从测试报告的 tags 中看到,有多少个用来在对于的 tags 执行的,而且在具体的用例日志中也看到报告是通过合并得到的,大致的过程就是这样子啦

  • 在我们自己产品的使用中,有具体的效率对比

提升的速度不多,原因是我分配到各节点的用例不均匀,但这个起码从本质上提高了自动化测试执行的效率,只要分配好执行的用例,效率肯定会很明显的提高的


四、最后说几句

前些天写那篇简单入手移动端并发自动化测试其实是个未成品,后面我们测试团队也按照本文的思想将并发框架改良,也很好地实现了移动端的并发自动化测试,当然之前还看到小红书的那个,我们现在也计划做成那个样子,docker 能很好地发挥资源优势,大家都可以多结合 docker 去做设计测试解决方案

还是回到那句,去年做了一大堆技术,今年就追求做到极致,其他还不仅是自动化测试,像我之前写的那个用Anyproxy+Moco做的 mock 服务器,我自己都将那个服务器迭代了 5 个版本了,放弃了 moco 和分离了数据,服务器的操作更加灵活,过几天有空的话可能也会继续分享一下我的 mock 服务器改良版,还有接口自动化测试的,以前一直是苦于环境,有很多测试数据是一次性的,那现在可以用 docker 对接口测试环境进行管理,执行测试或重现问题时可以自动构建环境,结合微服务的思想将数据和程序分离,然后,这样一次性的数据也可以多次使用了,所以今年就是要把去年的一大堆东西做到真正高效地解决测试的难题以既能保证质量,又能快速迭代地去响应客户需求,争得更多的市场,好吧,说那么多,希望大家也一起加油,把 2017 年做得极致,谢谢

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 43 条回复 时间 点赞

当然,除了用来做自动化测试,还可以用来做并发爬虫,有那么多个浏览器去做,当然会更高效,我自己最多还试过 10 个浏览器并发的,没毛病

恒温 将本帖设为了精华贴 03月29日 22:29

随着 docker 的出现,使用 selenium 做浏览器云测试已经没有太多的成本了。

这个测试报告是用的什么库?

docker 趋势很牛叉,现在基本上都在往 devops 发展。

恒温 #3 回复

这就是技术改变效率,个人觉得资源问题就是根本问题

robotframework 自带的,自己做了一点二开

devops 更多地是解决开发和运维之间的痛点,docker 只是其中一个载体或工具,更多地是我们应该落地怎么样的方案来解决和提升在产品研发过程中的应变能力,时代变化得太快了

不错,正弄这个,有点卡壳了。

这类框架的开发从来都不是问题,最终会出问题的地方就是维护。

这个是在 Ubuntu 基础上的 chrome 或 Firefox 镜像吧,要是需要 IE 的就不好搞了。

ting #10 回复

是的,尤其是镜像升级

我也提一下,其实我上面说的要做很多人都可以做到,关键是有多少人是能真正落地来解决问题的,不以解决问题为出发点的技术设计都只是炫技,华而不实,有输入要考虑价值

以前做电商自动化测试的时候,发现自动化测试数据的污染非常难搞,当时还没有 docker, 现在已经完全不是问题了。

simple #14 回复

这就是进步啊,现在工具和技术都很成熟

技术很多,落地是关键。并发是提高效率的利器。

现在我们的落地卡在写用例了,大家都没时间写用例。。。

陈恒捷 #16 回复

写覆盖度高的用例或许可以启到 1 个顶 3 个的作用,关键还是测试设计,不过时间还是刚需

terrychow #17 回复

我也是广州的,要不咱们加个微信交流交流?

陈恒捷 #18 回复

好,我们上周在 wetest 的沙龙见过面的,我就坐在你旁边😀

哈哈,原来见过面啦,幸会幸会~

之前手写的类似的框架,并没有给测试用例打 tag,每跑一个,都是找空闲的 docker instance,感觉比较合理啊,不然怎么最优化测试的分布又是个问题。

问题有些用例是有关联的,所以做好标签分类的话还是比较有用的

赞一个,补充一下如果想用 vnc 连接,需要自己设置密码,要改一下镜像。

鼓励楼主还有哪些 docker 方面的实践,都分享出来。 另外如果楼主是单点 docker 的话。 建议删除 docker0. 新建 br0 虚拟网桥然后把 docker 和宿主机都连到 br0 上来。然后用 none 模式启动,pipework 设置静态 ip。 这样就不用做宿主机:容器 端口映射了。 外部可直接通过 ip 访问

不错,不错

孙高飞 #23 回复

可以的,如果做持久化的容器的话用固定 ip 比较好,我们这边也考虑用 docker 做测试环境的集成,测试环境对 ip 有强依赖,所以也是会用固定 ip 或 “母鸡” ip 的

testly #24 回复

谢谢哈

terrychow #25 回复

但是集群化以后,就没办法固定 ip 了。只能端口映射。我们转集群的时候大家抱怨最多的就是没办法 ssh 进去看 log 了。要多几个步骤才能进入到容器里面

testng docker-selenium 也可以完成对应场景
不过我用的 rspec capybara docker-selenium 实现类似的场景 这个报表真赞 你的项目能分享下吗 求 github 地址 ,最近在学 python 看看这边的自动化如何去做

qilei #28 回复

测试报告是 roboframwork 自带的,我是汉化了和做了一点小二开,没放 github,放的话会在这里备注一下哈,谢谢你

楼主这套框架很值得学习借鉴,好东西。
测试数据的痛点,docker 的学习,楼主加油。

zyanycall #30 回复

测试数据可以用 docker 镜像化保存,让测试数据也带版本号,谢谢鼓励,我也会继续改进方案的

linux 版的 chrome 或 Firefox 做自动化,和 PC 上的浏览器差距大么
这几天我也试用了官方的镜像 ,但是不能镜像 pc 的浏览器,不清楚区别,是否会有兼容性的毛病

Baozhida #32 回复

其实把浏览器看做你的 webapp 的沙盒就好了,看起来肯定有所区别,但浏览器本来加载运行 web 的原理是一致就好,兼容问题或多或少会有,但更多是浏览器和环境的兼容,应用和浏览器的兼容只要浏览器版本一致的话就基本差不多的,反正用 air 版的思维去理解就好了

你好,我有一些问题想向你请教一下,方便留个邮箱或者微信号吗

我做的比较简单,没有用其他任何框架,直接就是最原始的多进程开启多个浏览器。。。

从易用易维护出发就好,不用框架也是没问题的

@terrychow 你好,本人最近刚好在寻求这方面的自动化测试方案,请问 docker-selenium 的方式资源开销大吗,比如如果要模拟并发 500 个用户同时进行用户登录操作,这个对硬件的要求是不是很高。8 核 16G 内存的主机大概能够支持多少数量级的并发呢?

Nonkr #37 回复

你可以试试,但这样并发你主要是测页面性能还是后台性能,后台的话没必要这样做 其他压测工具就好 如何是页面性能的话要看机器的情况了 但一般也只会在一定压力资源下看当前浏览器性能 所以如果是测性能的话没必要 不过你是想同时跑 500 个不同的自动化测试还是可以考虑的

terrychow #1 回复

我看你也是在 windows 上运行 docker,请问下怎么使用 vnc 访问容器内的网页。 我从镜像 selenium/standalone-chrome-debug 启动容器后,不知道到该如何去运行 vnc 或者说启动 vnc。 你是在 docker terminal 中 通过命令启动 vnc 还是 通过 vnc 的软件呢。

terrychow #38 回复

嗯,我明白,如果是测后台接口的话,我直接用其他工具可以做压测。我也不是为了测试页面的性能。只是为了模拟这种多用户并发访问进行页面操作的这种场景。

徐旻 #39 回复

我的 docker 是部署在 linux 上的,vnc 查看浏览器可以查看上面Docker-selenium中 Debugging 那一段,开放 5900 端口,还有楼上的评论也有说到怎么登录过去

terrychow #41 回复

问题已经搞定了,不过本人 linux 基本没有用过,所以很多时候一团雾水。 还是谢谢你

43楼 已删除
terrychow 浅谈测试工程化 - 以并发自动化框架为例 中提及了此贴 08月12日 22:21

@terrychow 楼主你好,你在文中提到了 docker 也可以解决测试数据污染这样的问题。我在做测试的过程中,每个接口之间的依赖性特别强,一个接口的操作往往需要另一个接口提供数据,这就导致了会创建一个流程下来会创建很多的测试数据,不知道有没有好的方法可以解决这个问题呢?谢谢

tammy212 #47 回复

docker 就是有这个好处,做接口测试,肯定有一套基础的测试数据,这套数据就是存储在测试中要用到的基础数据库,docker 可以将数据库以镜像的形式版本化,以及挂载不同的数据卷,这样的话就可以做到测试前的数据和测试后的数据是分开的,要执行第二次的测试,其实只要还原一下到基础数据库就好,以前的老办法就是直接在测试数据库上删数据,或者导出一些 sql 做冷备份,对比现在,只要一步还原就好,而且速度很快

terrychow 测试服务化小试-RobotFramework 测试库云构建 中提及了此贴 11月08日 10:53
terrychow [該主題已被刪除] 中提及了此贴 07月19日 20:33
需要 登录 後方可回應,如果你還沒有帳號按這裡 注册