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

terrychow · March 29, 2017 · Last by terrychow replied at August 15, 2017 · 4707 hits
本帖已被设为精华帖!

一、前言

  • 最近一直在还去年的技术债,去年我们测试团队投入一大堆测试技术,但没有多少个是做精的,那今年的目标就是做到极致,去年团队落地了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个浏览器并发的,没毛病

恒温 将本帖设为了精华贴 29 Mar 22:29

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

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

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

恒温 回复

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

玄月指光 回复

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

kanelee 回复

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

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

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

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

terrychow #12 · March 30, 2017 作者
ting 回复

是的,尤其是镜像升级

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

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

terrychow #15 · March 30, 2017 作者
simple 回复

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

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

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

terrychow #17 · March 30, 2017 作者
陈恒捷 回复

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

terrychow 回复

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

terrychow #19 · March 30, 2017 作者
陈恒捷 回复

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

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

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

terrychow #22 · March 30, 2017 作者
Minwei Shen 回复

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

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

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

不错,不错

terrychow #25 · March 30, 2017 作者
孙高飞 回复

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

terrychow #26 · March 30, 2017 作者
testly 回复

谢谢哈

terrychow 回复

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

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

terrychow #29 · March 30, 2017 作者
qilei 回复

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

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

terrychow #31 · April 05, 2017 作者
zyanycall 回复

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

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

terrychow #33 · April 12, 2017 作者
Baozhida 回复

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

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

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

terrychow #36 · April 27, 2017 作者

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

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

terrychow #38 · May 03, 2017 作者
Nonkr 回复

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

terrychow 回复

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

terrychow 回复

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

terrychow #41 · May 04, 2017 作者
徐旻 回复

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

terrychow 回复

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

43Floor has been deleted

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

tammy212 回复

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

terrychow [Topic was deleted] 中提及了此贴 19 Jul 20:33
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up