今天先聊聊如何搭建自动化测试框架,主要会聊聊一些思路上的东西,从一个最简单的demo到把一个框架该有的组件都搭建好。本文主要以web自动化为例子,使用的语言是js。
在了解什么是自动化测试框架之前,先了解一下什么叫框架?框架是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面,而后者是从目的方面给出的定义。
对于自动化测试框架大致包含以下的内容:
自动化测试工具(selenium、puppeteer…)
Runner(Jest…)
日志(logger)
报告(reportor)
持续集成
目前,对于web端UI自动化比较主流的工具有selenium、webDriver。而在这里选择的是Puppeteer,先来了解下puppeteer。
在chrome 59 chrome团队支持了headless模式,在Headless模式下,用于自动化测试和不需要可视化用户界面的服务器。例如,你想在一个网页上运行一些测试,从网页创建一个PDF,或者只是检查浏览器怎样递交URL。
Puppeteer是谷歌官方出品的一个通过DevTools协议控制headless Chrome的Node库。可以通过Puppeteer的提供的api直接控制Chrome模拟大部分用户操作来进行UI Test或者作为爬虫访问页面来收集数据。
Puppeteer 核心功能:
利用网页生成PDF、图片
爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染)
可以从网站抓取内容
自动化表单提交、UI测试、键盘输入等
帮你创建一个最新的自动化测试环境(chrome),可以直接在此运行测试用例
捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题
Puppeteer是使用node语言进行开发的,在使用中你可以使用async/await异步解决方案,async/await可能是目前为止最简单的异步方案了。
很强大是不是,接着我们去学习下puppeteer的接口文档,接着开始写我们的demo。
该用例是直接使用puppeteer,先launch一个browser然后newPage,接着开始写case。如果你想执行可以把then后的内容改成访问百度界面的。如下图,
我们来看下整体的框架,如下图,图中直接使用Puppeteer。
对于以上的case,假如我要在写一条case,需要新建一个js文件,然后先launch一个browser然后newPage,接着开始写case。在这样的一个过程中我们可以看到我们每次都要launch browser,close browser,当然还有其他的问题比如怎么快速的执行多个用例等等,那么该如何解决这个问题呢?这时候考虑引入一个Runner的概念。
对于Jest,在并发执行可以保持最高的性能,在沙盒模式下每个测试都有一个干净的环境。Jest在做UT、AT有着很成功的应用。接着我们在框架里面加入lifecycle去管理一些资源。需要去做一些setup、teardown的工作。
在这里抽象了一个environment(下图左),去统一管理测试过程中的一些资源,在这里引入了setup、teardown,声明全局的browser、page变量。而对于case(下图右),使用Jest的case编写规则去写,首先是一个describe,类似test suite,在describe可以写多个it,一条的it代表一条的case,你就可以在一个文件里写多条的case。对比下二中的case此时我们不需要在每次执行launch了。
接着看下整体的框架图,可以看到我们把jest给加入了
对于上面的case我们把对页面元素的建模跟对应的操作以及测试方法都写到同个class里面了。对于这样的case,如果改动了某个元素需要改动很多个的文件,维护成本很高,这是我们不希望看到的。接下来我们引入了POM。
POM的全称是Page Object Model。POM模型要求将一个页面上所有功能/可重用组件写到一个class文件中,它存在以下规则。
1.Page Object Model is a design pattern to create Object Repository for web UI elements.
2.Under this model, for each web page in the application, there should be corresponding page class.
3.This Page class will find the WebElements of that web page and also contains Page methods which perform operations on those WebElements.
对于三中的代码很明显没有遵循POM,接着我们进行改进。
在这里我抽象出一个pages,把不同界面的建模以及对元素的操作放在一个文件夹下,在case层只有测试方法。
在使用POM的过程中我还做了一件事情,抽象出driver层,对puppeteer的API进行封装,封装的意义有两方面为了支撑其他的工具比如selenium,统一接口,更好的做兼容性测试,(puppeteer支持的browser类型比较少);另一方面,对于driver这类的工具在ui。
测试工程其实不会用到所有的大概能用上十几个method,我们可能对它进行封装让它更好用,比如可以在click前waitFor这个element出现,这样做就不需要在写case的时候每次click前都wait了。
接着我们来看下整体的框架:
对于这样的框架我们能很好的工作了,接下来需要加的是啥呢?
loggger、report、assert是框架的必须部分。
logger需要统一的管理打印到console或者某个file,logger可以帮助我们更快的定义问题对于logger可以分为两类一个应用本身的log,一个测试代码的log,根据需要收集;report是在测试结束后把结果展示出来,可以是dashboars可以是html,告诉case的整体情况,以及错误时候的信息,当然还可以是更详细信息,比如说每一步的步骤信息等;Assert这里是采用了Jest自带了,觉得Jset自带的expect已经很强大了,当然如果你需要用别的或者封装也是可以的。我们接着看下代码(如下图),对于这些我们去使用是很方便的集成的,易于集成也是衡量一个第三方library的一个重要指标。
对于框架层加了两个模块进去。
对于框架而言,通常会留有一个Helper,把跟测试相关的工具放在这里。方便使用与管理。我们看下框架。
首先,持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。自动化测试作为在持续集成中的一个重要环节,我们需要在执行UT/IT后接着执行AT,更早的发现bug。在这里可以使用docker搭建puppeter的运行环境,在jenkins上通过pipeline在docker中执行测试。
以上就是本文的主要内容,希望看完这篇文章大家可以思考一些问题,对于这样的设计有何优化建议?在编写测试中可能会遇到哪些问题?我来说下,如何支持多个browser?测试太慢如何通过缓存提供web 元素的加载?面对这些该如何解决呢?
最后的最后,该框架的源码在github上,https://github.com/summergan/EndToEnd
目前只有文章中的demo,后续有时间会继续更新。
本文未经授权不得转载,如需转载请于51Testing小编联系。