cover_image

WebUI自动化录制用例的探索与实践

Secret 信也科技拍黑米 2023年07月27日 03:47

1. 业务背景

随着Web技术的快速发展和平台的不断迭代更新,回归测试变得越来越重要。传统的手工测试耗时且费力,UI自动化的出现提高了回归效率,但同时也带来了更高的测试成本。因此,如何高效地编写自动化用例成为我们面临的一项挑战。

我们先回顾一下目前常用的编写UI自动化用例的方式:

图片

编写UI自动化用例常用方式

为了解决这些问题,我们期望能实现这样一些功能:

(1)在操作界面的同时进行录制,操作完成就能生成测试用例。

(2)本地无需搭建任何环境,生成和执行用例都由测试平台完成。

(3)测试用例能够结构化入库统一管理,便于维护。

2. 技术调研

目前我们的测试平台已经支持测试用例管理,主要突破点是将录制与平台融合,提高用例的编写效率。

2.1 主流录制工具种类

初期调研了几种主流的录制工具,先做下简单的介绍:

2.1.1 Selenium IDE

Selenium IDE是Selenium工具套件中的一个组件,是用于开发Selenium测试用例的工具。它是Chrome和Firefox浏览器的一个扩展工具,可以通过录制回放功能创建测试脚本。

2.1.2 Playwright

Playwright是微软开源的WebUI自动化测试框架。与Selenium类似,但拥有更强大的自动化能力。同时也支持录制功能,我们只需手动操作浏览器,它会录制我们的操作,然后自动生成代码脚本。

2.1.3 UIRecorder

UIRecorder是阿里巴巴的一款UI录制和回归测试工具,用于录制浏览器页面UI的操作。可以在自测的同时,完成测试过程的录制,生成JavaScript测试脚本代码。回归测试过程中利用生成的脚本代码, 使用 Mocha 对自测过程进行回放,以达到零成本做自动化回归测试的目的。

<table>  <tr>    <th>录制工具</th>    <th>Playwright</th>    <th>SeleniumIDE</th>    <th>UIRecorder</th>  </tr>  <tr>    <td>是否开源</td>    <td></td>    <td></td>    <td></td>  </tr>  <tr>    <td>支持浏览器</td>    <td>Chrome、Firefox、Safari、Edge</td>    <td>Chrome、Firefox</td>    <td>Chrome、Firefox、</td>  </tr>  <tr>    <td>依赖环境</td>    <td>Python</td>    <td>浏览器插件</td>    <td>NodeJS</td>  </tr>  <tr>    <td>生成脚本语言</td>    <td>Java、Python、Node.js等</td>    <td>Java、Python、JavaScript</td>    <td>JavaScript</td>  </tr>    <tr>    <td>录制与生成脚本分离</td>    <td></td>    <td></td>    <td></td>  </tr></table>

2.2 主流录制工具对比

这些录制工具都是在录制完成后生成脚本,相对来说SeleniumIDE对环境的依赖更少,但是需要将脚本先导出然后再上传到测试平台,操作不够便捷。

再次深入调研发现:UIRecorder底层将录制和生成脚本解耦,录制逻辑由浏览器插件实现,不依赖本地环境。这不就是我们想要的吗? 于是我们决定选择UIRecorder进行进一步的探索。

3. 实现过程

3.1 录制工具适配测试平台

首先了解下UIRecorder的录制原理:

图片

UIRecorder录制原理

录制功能主要由 Chrome Extension 和 Node Process 两部分组成:

Chrome Extension 会对当前浏览器进行全局事件监听,当触发某个事件(比如 click)时,即获取当前操作元素的节点信息,同时通过 WebSocket 发送指令(开始录制、录制、结束录制)、数据(事件类型、节点信息)至 Node Process。

Node Process  接收到 Chrome Extension 的请求指令、数据,将其记录在一个数组中,当 Chrome Extension 发起结束录制指令时,结合记录队列和配置的脚本模版,生成测试用例脚本至指定目录(如 sample/test.spec.js )。

对于我们的需求来说,只需要用到Chrome Extension部分,主要是这两个文件: foreground.js 和 background.js

foreground.js 记录页面操作并捕获对应的元素,将操作发送给background.js

background.js 接收操作记录后通过WebSocket传输给Node Process服务,我们需要修改的就是将数据传输给我们的测试平台

原始通信代码:

```javascriptfunction sendWsMessage(type, data){    if(wsSocket){        var message = {            type: type,            data: data        };        wsSocket.send(JSON.stringify(message));    }}```

修改成调用接口传给测试平台:

```javascriptfunction sendWsMessage(type, data){          fetch(baseUrl + '/api/generalMsg/save_record_step', {        method: 'POST',        body: JSON.stringify({            recordId: recordId,            stepInfo: { type: type, data: data}        }),        headers: {'Content-type': 'application/json; charset=UTF-8'}}).then(res => res.json()).then(console.log)}```

基本的通信已经完成了,实践过程中发现传过来的部分操作是原始操作,比如点击(click)是由mouseUp、mouseDown两个操作组成,在Node Process服务中会将原始操作进行合并,需要将这部分逻辑迁移到background.js中:

```javascriptfunction clickFilter(cmdInfo){                // 合并为click,增加兼容性                var cmd = cmdInfo.cmd;                var data = cmdInfo.data;                if(lastCmdInfo1 && lastCmdInfo1.cmd === 'mouseDown'){                    var lastCmdData = lastCmdInfo1.data;                    if(cmd === 'mouseUp' &&                        cmdInfo.window === lastCmdInfo1.window &&                        cmdInfo.frame === lastCmdInfo1.frame &&                        lastCmdData.path === data.path &&                        Math.abs(lastCmdData.x - data.x) < 20 &&                        Math.abs(lastCmdData.y - data.y) < 20                    ){                        // 条件满足,合并为click                        cmdInfo = {                            window: cmdInfo.window,                            frame: cmdInfo.frame,                            cmd: 'click',                            data: data,                            text: cmdInfo.text                        };                    }                }                lastCmdInfo1 = cmdInfo;            }```

断言支持在录制过程中添加,UIRecorder的断言方法与测试平台存在差异,需要获取测试平台的断言方法,提供给录制工具使用:

```javascriptfunction connectServer(port){    recordId = port    const fetchAPI = async () => {        try {            const response = await fetch(baseUrl + '/api/generalMsg/auto_method_assert')            if (response.status === 200) {                 const data = await response.json()                 expectMethods = data.data                 recordConfig = getConfig();                 GlobalEvents.emit('updateConfig', recordConfig);                } else {                    console.log('请求异常')                 }                } catch (err) {                     console.log(err)                    }                }    fetchAPI() }```

接着需要实现的是测试平台实时展示操作步骤,实现方式如下:

图片

实时展示步骤

3.2 启动方案选择

录制工具已经基本适配测试平台,接下来要解决的是如何在平台上启动录制工具。

方案1:  浏览器安装录制插件

前面也说到录制工具是一个浏览器插件,首先想到的是在浏览器中安装此插件,点击录制时打开新的录制窗口完成录制。理想很美好,现实却是残酷的,录制工具会在页面注入脚本,这些脚本对所有的页面都生效,会影响其他页面的正常使用,显然这不符合我们的需求。

方案2: Nodejs启动浏览器

实现方式类似原生UIRecorder的启动方式,Nodejs启动新的浏览器时加载插件,不会对其他页面有影响,但是需要安装Nodejs,也不太符合我们的需求。

方案3: Python+Selenium启动浏览器

写过UI自动化代码的测试同学对Selenium应该不陌生,功能实现上和Nodejs类似,也是依赖环境的。

那有没有不依赖环境的方式呢? 

答案是有的:

>pyinstaller可以打包Python程序变为可执行文件,让其可以在任何windows下正常运行而无需Python的解析。

使用方法如下:

(1)安装pyinstaller

pip install pyinstaller

(2)执行打包命令

pyinstaller -D -w -i  xxx\xxx.ico  xxx\xxx.py
-D 表示打包成一个文件夹,里面有多个文件,启动较快-F 表示打包成一个单独的exe文件,启动较慢-w 表示运行exe文件后不出现cmd命令窗口-i 指定exe文件的图标

通过上面的操作已经将Python程序打包完成,继续解决浏览器调用本地exe程序的问题,主要分为三步:

第一步:编写注册表文件

图片注册表文件

第二步:保存注册表为xxx.reg 然后双击执行

第三步:前端代码中进行调用

window.open('myrecord://xxx''_self')

通过将程序打包和调用,实现一键启动录制,测试同学可以轻松地开始录制,启动流程如下:

图片

启动录制工具

3.3 简化安装步骤

Python打包时我们选择了启动较快的方式,将程序打包成文件夹,需要将文件夹下载到本地,还需要手工创建注册表文件,操作略显繁琐。

为了简化安装步骤,尝试将打包后的文件夹和注册表文件制作成安装包,实现一键安装。

选择nsis工具进行制作,具体步骤不再赘述,可参考 https://zhuanlan.zhihu.com/p/505941644

另外需要在生成的nsis脚本中增加启动exe程序的注册表配置:

 WriteRegStr HKCR "myrecord" "" "myrecord Protocol"  WriteRegStr HKCR "myrecord" "URL Protocol" ""  WriteRegStr HKCR "myrecord\DefaultIcon" "" "cmd.exe,1"  WriteRegStr HKCR "myrecord\shell" "" ""  WriteRegStr HKCR "myrecord\shell\open" "" ""  WriteRegStr HKCR "myrecord\shell\open\command" "" "cmd /c start $INSTDIR\record.exe %1"

最后将安装包上传到测试平台,下载后双击即可完成安装啦!

4. 总结

通过前面的探索与实践,我们已经顺利解决了文章开头提到的问题,界面操作完成后就能生成对应的自动化用例,使UI自动化测试变得更加简单高效。

UI自动化是一个不断发展的领域,新技术和工具的涌现为我们带来了更多的可能性。我们也需要持续关注和学习新技术,探索如何应用到日常的自动化测试中,不断提升UI自动化的效率和质量。

参考资料

[1] UIRecorder: https://www.yuque.com/artist/uirecorder/hbqzpl

[2] Playwright: https://playwright.dev/docs/intro

[3Selenium IDE: https://www.selenium.dev/selenium-ide/

[4] 启动exe程序: https://blog.csdn.net/m0_61173140/article/details/128203176

[5] 制作安装包: https://zhuanlan.zhihu.com/p/505941644

作者介绍

图片

招聘信息

Java、大数据、前端、测试等各种技术岗位热招中,欢迎了解~

更多福利请关注官方订阅号信也科技拍黑米拍码场

喜欢请点击↓↓↓

继续滑动看下一个
信也科技拍黑米
向上滑动看下一个