详细讲解木偶师前端自动化测试实践
引起
目前我们正在持续开发一个几十页十万行代码的项目。随着产品的变化,这样的问题总会出现。在添加或修改一些业务逻辑或功能(尤其是通用逻辑)时,这些通用逻辑或组件往往会涉及到其他地方的一些问题。由于测试人员有限,我们很难在完成一个模块单元后重新测试所有功能。同时,由于环境和数据的差异(以及开发过程中对代码完整性的疏忽),代码在一些特殊数据的分析和显示上会出现问题,这在开发和测试中很难发现。一般来说,我们希望有这样一个工具来帮助我们解决上述问题:
代码和函数发生变化后,可以自动访问各个函数的页面,对于大量的数据内容检测出问题,进行批量访问,检测不同数据的显示是否存在问题,尽量做到测试和代码功能不耦合,避免每次安装新的函数都需要修改测试用例,以过高的成本维护常规的测试任务,及时发现数据平台对新数据显示的完备性。其中,最重要的问题是将测试代码与函数解耦,避免每次迭代和修改都增加新的测试用例。我们如何做到这一点?首先,我们来梳理一下测试平台的功能。
功能设置
因为我们的平台主要是显示数据,所以我们在测试过程中主要关注的是日常显示数据,并不会先处理一些复杂的表单操作。鉴于上述问题,我们针对自动化测试工具的以下功能:
依次访问每一页,访问每一页的具体内容,如时间切换、页签切换、页面切换、表格展开行等。对于数据表中的详细链接,选择前100个进行访问,继续下钻页面的测试,捕获页面中的错误请求,捕获错误信息,并进行统计和报告。根据上面的梳理,我们可以把整个应用程序分成几个测试单元。
页面单元,检测各功能页面访问的稳定详情页单元,根据页面的数据列表批量跳转详情页,检测不同参数下详情页的稳定功能单元,用于检测页面和详情页的各种显示类型点击切换后是否产生错误
通过这种划分,我们为每个单元编写具体的测试逻辑用例,避免在添加新的函数和页面时频繁修改测试用例。
操纵木偶的人
有了以上要求,我们来看看木偶戏的功能和特点是否能满足我们的要求。
文档地址
木偶是一个节点库,它提供了一个高级的应用编程接口来通过开发工具协议控制铬或铬。默认情况下,木偶操作器是无头运行的,但是可以通过修改配置文件来无头运行。
我们可以使用puppet完成以下任务:
访问页面、截图、自动进入键盘、提交表单、模拟点击等用户操作等等。让我们通过一些小案例来介绍它们的基本功能:
访问具有ba认证的网站
木偶师可以创建一个页面实例,并使用goto方法访问页面。页面包含一系列方法,可以对页面执行各种操作。
(async()={ const browser=wait puppeter . launch();const page=wait browser . NewPage();//ba身份验证awaitpage。验证({用户名,密码});//访问await page . goto(' https://example.com ')页面;//截图awaitpage .截图({ path : ' example . png ' });wait browser . close();})();访问登录页面并登录
首先,对于SPA(单页应用),我们都知道客户端代码只有在页面进入后才开始渲染。我们需要等到页面内容呈现出来,再做相应的操作。我们有以下方法来使用它
等待直到
木偶师为页面访问、切换等提供了等待时间参数。以确定在页面跳转被认为完成之前满足了哪些条件。包括以下事件:
Load-DOMContentLoaded当页面的Load事件被触发时-NetworkIdl0当页面的DOMContentLoaded事件被触发时-NetworkIdl2当没有更多的网络连接时(至少500毫秒后)-当只有两个网络连接时(至少500毫秒后),我们可以确定在通过waitUnitl完成所有页面请求后,页面已经被访问。
等待
等待方法可以在指定的操作完成后解决
//等待selectorawait page.waitFor('。foo’);//等待1秒wait page . wait for(1000);//等待predicatewait page . wait for(()=!document.querySelector('。foo’);我们可以使用waitForSelector方法在登录框成功呈现后登录
//等待密码输入框呈现await page . wait for(' password ');//输入用户名awaitpage.type('输入# username ',' username ');//输入密码awaitpage.type('输入# password ',' test pass ');//点击登录按钮await promise . all([页面。等待navigation(),//跳转完成后,解析页面。点击('按钮。login-button '),//点击此链接会间接导致导航(跳转)];wait page . wait for(2000)//get cookies const cookies=await page。cookies()分批访问列表中的链接
主要使用页面实例的选择器功能
const table=等待页面。$('.表)常量链接=等待表。$$eval('a.link-detail ',links=link . map(link=link . href));//循环访问链接.用于错误和访问监控
木偶师可以在页面访问过程中监听错误和请求,让我们捕捉页面访问错误并上报,这也是我们测试需要的基本功能~
//当发生页面上js代码没有捕获到的异常时触发。page . on(' page error ',()={})//当页面崩溃时触发。Page.on('error ',()={})//触发page.on('request')//当页面请求收到相应的响应时触发。Page.on('response ')通过上面的小案例,我们发现puppet的功能非常强大,完全可以满足我们上面对页面自动访问的要求。接下来,我们为测试单元编写一个单元用例
最终功能
通过我们对上述测试单元的规划,我们可以规划我们的测试路径
访问网站-登录-访问页面1-进行基本单元测试-获取详细页面跳转链接-依次访问详细页面-进行基本单元测试
-访问第2页.
因此,我们可以分解几个主要的类和几个测试单元来进行各种测试
//包括基本测试方法、日志输出等类Base {}//详细页面单元,并执行一些基本单元测试,如类PageDetal扩展Base {}//页面单元。并获取和访问详细页面类Page extended Page detal { }//依次进行登录等操作,并依次访问页面单元测试类Root extends Base { }。同时,当功能页面发生变化时,我们如何跟踪测试的变化?我们可以给我们测试的函数添加一个自定义标签test-role,并在测试过程中根据自定义标签编写测试逻辑。
例如,对于时间切换单元,我们来简单介绍一下:
//1.获取元素const time switch=awaitpage。测试单元的$('[test-role=' time-switch ']');//如果页面上没有timeSwitch,就不需要测试if(!时间开关)返回//2。时间开关开关按钮常量按钮=时间开关。$ $ ('.时间开关按钮')//3。循环单击按钮(让I=0;长度;I) {const button=buttons[i] //点击按钮wait button.click() //关键点!在等待相应内容出现的同时,仅当页面访问成功时,尝试{ await page . wait for('[test-role=' time-switch-content ']')} catch(error){ reporter error)}//截图await page.screenshot以上只是简单的访问内容测试。我们可以根据用例单元编写自己的测试逻辑。在我们的日常开发中,我们只需要将相应的测试角色添加到要测试的内容中。
摘要
根据上面的功能划分,我们将整个应用程序分割成不同的测试单元进行单元测试。需要注意的是,目前我们只测试页面的可访问性,只验证用户在进行各种操作、访问各种页面单元时,页面是否会出错。页面的具体显示效果还没有测试,会和页面的功能内容耦合,所以需要单独编写测试用例。
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:详细讲解木偶师前端自动化测试实践是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。