如何搭建自动化测试框架
序
今天先聊聊如何搭建自动化测试框架,主要会聊聊一些思路上的东西,从一个最简单的 demo 到把一个框架该有的组件都搭建好。本文主要以 web 自动化为例子,使用的语言是 js。
一、什么是自动化测试框架
在了解什么是自动化测试框架之前,先了解一下什么叫框架?框架是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面,而后者是从目的方面给出的定义。
—百度百科
对于自动化测试框架大致包含以下的内容
自动化测试工具(selenium、puppeteer…)
Runner(Jest…)
日志(logger)
报告(reportor)
持续集成
二、使用 puppeteer 开始写一个最小的 demo
2.1 工具选型
目前,对于 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。
2.2 测试用例
该用例是直接使用 puppeteer,先 launch 一个 browser 然后 newPage,接着开始写 case。如果你想执行可以把 then 后的内容改成访问百度界面的。如下图,
[图片上传中...(image.png-17f1b4-1548390079293-0)]
我们来看下整体的框架,如下图,图中直接使用 Puppeteer。
对于以上的 case,假如我要在写一条 case,需要新建一个 js 文件,然后先 launch 一个 browser 然后 newPage,接着开始写 case。在这样的一个过程中我们可以看到我们每次都要 launch browser,close browser,当然还有其他的问题比如怎么快速的执行多个用例等等,那么该如何解决这个问题呢?这时候考虑引入一个 Runner 的概念。
三、使用 Jest 进行 lifecycle 管理
3.1 了解 Jest
Jest parallelizes test runs across workers to maximize performance. Console messages are buffered and printed together with test results. Sandboxed test files and automatic global state resets for every test so no two tests conflict with each other.
对于 Jest,在并发执行可以保持最高的性能,在沙盒模式下每个测试都有一个干净的环境。Jest 在做 UT、AT 有着很成功的应用。接着我们在框架里面加入 lifecycle 去管理一些资源。需要去做一些 setup、teardown 的工作。
3.2 Jest+puppeteer
在这里抽象了一个 environment(下图左),去统一管理测试过程中的一些资源,在这里引入了 setup、teardown,声明全局的 browser、page 变量。而对于 case(下图右),使用 Jest 的 case 编写规则去写,首先是一个 describe,类似 test suite,在 describe 可以写多个 it,一条的 it 代表一条的 case,你就可以在一个文件里写多条的 case。对比下二中的 case 此时我们不需要在每次执行 launch 了。
接着看下整体的框架图,可以看到我们把 jest 给加入了
对于上面的 case 我们把对页面元素的建模跟对应的操作以及测试方法都写到同个 class 里面了。对于这样的 case,如果改动了某个元素需要改动很多个的文件,维护成本很高,这是我们不希望看到的。接下来我们引入了 POM.
四、POM
4.1 了解 POM
POM 的全称是 Page Object Model。POM 模型要求将一个页面上所有功能/可重用组件写到一个 class 文件中,它存在以下规则
Page Object Model is a design pattern to create Object Repository for web UI elements.
Under this model, for each web page in the application, there should be corresponding page class.
This Page class will find the WebElements of that web page and also contains Page methods which perform operations on those WebElements.
image.png
对于三中的代码很明显没有遵循 POM,接着我们进行改进。
4.2 采用 POM 模型编写代码
在这里我抽象出一个 pages,把不同界面的建模以及对元素的操作放在一个文件夹下,在 case 层只有测试方法。
image.png
在使用 POM 的过程中我还做了一件事情,抽象出 driver 层,对 puppeteer 的 API 进行封装,封装的意义有两方面为了支撑其他的工具比如 selenium,统一接口,更好的做兼容性测试,(puppeteer 支持的 browser 类型比较少);另一方面,对于 driver 这类的工具在 ui
测试工程其实不会用到所有的大概能用上十几个 method,我们可能对它进行封装让它更好用,比如可以在 click 前 waitFor 这个 element 出现,这样做就不需要在写 case 的时候每次 click 前都 wait 了。
接着我们来看下整体的框架:
对于这样的框架我们能很好的工作了,接下来需要加的是啥呢?
五、Logger&Report&Assert
loggger、report、assert 是框架的必须部分。
logger 需要统一的管理打印到 console 或者某个 file,logger 可以帮助我们更快的定义问题对于 logger 可以分为两类一个应用本身的 log,一个测试代码的 log,根据需要收集;report 是在测试结束后把结果展示出来,可以是 dashboars 可以是 htm l,告诉 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,后续有时间会继续更新。
版权声明: 本文为 InfoQ 作者【夏兮。】的原创文章。
原文链接:【http://xie.infoq.cn/article/4afa6e191a8328e6205786551】。
本文遵守【CC BY-NC】协议,转载请保留原文出处及本版权声明。
评论