puppeteer登录后点击_Puppeteer自动化测试实践

本文介绍了使用Puppeteer进行自动化网页测试,以解决代码修改后自动检测页面错误、批量数据访问等问题。通过Puppeteer的功能,如waitUntil、waitFor等,实现对SPA应用的登录、页面访问、错误监听等操作,将测试逻辑与功能解耦,降低维护成本。
摘要由CSDN通过智能技术生成
d0682e0f6d15b7a86ad67159db2c7896.gif                

本篇内容将记录并介绍使用Puppeteer进行自动化网页测试,并依靠约定来避免反复修改测试用例的方案。主要解决页面众多时,修改代码导致的牵连错误无法被发现的运行时问题。

起因

目前我们在持续开发着一个几十个页面,十万+行代码的项目,随着产品的更迭,总会出现这样的问题。在对某些业务逻辑或者功能进行添加或者修改的时候(尤其是通用逻辑),这些通用的逻辑或者组件往往会牵扯到一些其他地方的问题。由于测试人员受限,我们很难在完成一个模块单元后,对所有功能重新测试一遍。同时,由于环境及数据的区别,(以及在开发过程中对代码完备性的疏忽),代码会在某些特殊数据的解析和和展示上出现问题,在开发和测试中很难去发现。总的来说,我们希望有一个这样的工具,帮我们解决上述几个问题:

  1. 在进行代码和功能改动后,能够自动访问各个功能的页面,检测问题

  2. 针对大量的数据内容,进行批量访问,检测对于不同数据的展示是否存在问题

  3. 测试与代码功能尽量不耦合,避免每次上新功能都需要对测试用例进行修改,维护成本太大

  4. 定期的测试任务,及时发现数据平台针对新数据的展示完备性

其中,最重要的问题,就是将测试代码与功能解耦,避免每次迭代和修改都需要追加新的测试用例。我们如何做到这一点呢?首先我们来梳理下测试平台的功能。

功能设定

由于我们的平台主要是进行数据展示,所以我们在测试过程中,主要以日常的展示数据为重心即可,针对一些复杂的表单操作先不予处理。针对上述的几个问题,我们针对自动化测试工具的功能如下:

  1. 依次访问各个页面

  2. 访问各个页面的具体内容,如时间切换、选项卡切换、分页切换、表格展开行等等

  3. 针对数据表格中的详情链接,选择前 100 条进行访问,并进行下钻页的继续测试

  4. 捕获在页面中的错误请求

  5. 对错误信息进行捕获,统计和上报

根据以上的梳理,我们可以把整个应用分为几个测试单元

  • 页面单元,检测各功能页面访问的稳定性

  • 详情页单元,根据页面的数据列表,进行批量的详情页跳转,检测不同参数下详情页的稳定性

  • 功能单元,用于检测页面和详情页各种展示类型点击切换后是否产生错误

517c21a260a0b8d5ff576a9181a35fec.png

通过这样的划分,我们针对各个单元进行具体的测试逻辑书写用例,这样就可以避免再添加新功能和页面时,频繁对测试用例进行修改了。

Puppeteer

带着上面我们的需求,我们来看下 Puppeteer 的功能和特性,是否能够满足我们的要求。

文档地址(https://zhaoqize.github.io/puppeteer-api-zh_CN/#/)

Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。Puppeteer 默认以 headless 模式运行,但是可以通过修改配置文件运行“有头”模式。

我们可以使用 Puppeteer 完成以下工作:

  • 访问页面,进行截图

  • 自动进行键盘输入,提交表单

  • 模拟点击等用户操作

  • 等等等等。

我们来通过一些小案例,来介绍他们的基本功能。

访问一个带有 ba 认证的网站

puppeteer 可以创建 page 实例,并使用 goto 方法进行页面访问,page 包含一系列方法,可以对页面进行各种操作。

(async () => {const browser = await puppeteer.launch();const page = await browser.newPage();// ba认证await page.authenticate({    username,    password  });// 访问页面await page.goto('https://example.com');// 进行截图await page.screenshot({path: 'example.png'});await browser.close();})();

访问登陆页面,并进行登录

首先,对于 SPA (单页面应用),我们都知道,当页面进入后,客户端代码才开始进行渲染工作。我们需要等到页面内容渲染完成后,再进行对应的操作。我们有以下几种方法来使用

waitUntil

puppeteer 针对页面的访问,切换等,提供了 waitUntil 参数,来确定满足什么条件才认为页面跳转完成。包括以下事件:

  • load - 页面的 load 事件触发时

  • domcontentloaded - 页面的 DOMContentLoaded 事件触发时

  • networkidle0 - 不再有网络连接时触发(至少 500 毫秒后)

  • networkidle2 - 只有 2 个网络连接时触发(至少 500 毫秒后)

通过 waitUnitl,我们可以当页面请求都完成之后,确定页面已经访问完成。

waitFor

waitFor 方法可以在指定动作完成后才进行 resolve

// wait for selectorawait page.waitFor('.foo');// wait for 1 secondawait page.waitFor(1000);// wait for predicateawait page.waitFor(() => !!document.querySelector('.foo'));

我们可以利用 waitForSelector 方法,当登录框渲染成功后,才进行登录操作

// 等待密码输入框渲染await page.waitFor('#password');// 输入用户名await page.type('input#username', "username");// 输入密码await page.type('input#password', "testpass");// 点击登录按钮await Promise.all([  page.waitForNavigation(), // 等跳转完成后resolve  page.click('button.login-button'), // 点击该链接将间接导致导航(跳转)]);await page.waitFor(2000)// 获取cookiesconst cookies = await page.cookies()

针对列表内容里的链接进行批量访问

主要利用到 page 实例的选择器功能

const table = await page.$('.table')const links = await table.$$eval('a.link-detail', links =>  links.map(link => link.href));// 循环访问links...

进行错误和访问监听

puppeteer 可以监听在页面访问过程中的报错,请求等等,这样我们就可以捕获到页面的访问错误并进行上报啦,这也是我们进行测试需要的基本功能~

// 当发生页面js代码没有捕获的异常时触发。page.on('pagerror', () => {})// 当页面崩溃时触发。page.on('error', () => {})// 当页面发送一个请求时触发page.on('request')// 当页面的某个请求接收到对应的 response 时触发。page.on('response')

通过以上的几个小案例,我们发现 Puppeteer 的功能非常强大,完全能够满足我们以上的对页面进行自动访问的需求。接下来,我们针对我们的测试单元进行个单元用例的书写

最终功能

通过我们上面对测试单元的规划,我们可以规划一下我们的测试路径

访问网站 -> 登陆 -> 访问页面1 -> 进行基本单元测试 -> 获取详情页跳转链接 -> 依次访问详情页 -> 进行基本单元测试

-> 访问页面2 …

所以,我们可以拆分出几个大类,和几个测试单元,来进行各项测试

// 包含基本的测试方法,log输出等class Base {}// 详情页单元,进行一些基本的单元测试class PageDetal extends Base {}// 页面单元,进行基本的单元测试,并获取并依次访问详情页class Page extends PageDetal {}// 进行登录等操作,并依次访问页面单元进行测试class Root extends Base {}

同时,我们如何在功能页面变化时,跟踪到测试的变化呢,我们可以针对我们测试的功能,为其添加自定义标签 test-role,测试时,根据自定义标签进行测试逻辑的编写。

例如针对时间切换单元,我们做一下简单的介绍:

// 1. 获取测试单元的元素const timeSwitch = await page.$('[test-role="time-switch"]');// 若页面没有timeSwitch, 则不用进行测试if (!timeSwitch) return// 2. time switch的切换按钮const buttons = timeSwitch.$$('.time-switch-button')// 3. 对按钮进行循环点击for (let i = 0; i < buttons.length; i++) {const button = buttons[i]// 点击按钮await button.click()// 重点!等待对应的内容出现时,才认定页面访问成功try {await page.waitFor('[test-role="time-switch-content"]')  } catch (error) {    reportError (error)  }// 截图await page.screenshot()}

上面只是进行了一个简单的访问内容测试,我们可以根据我们的用例单元书写各自的测试逻辑,在我们日常开发时,只需要对需要测试的内容,加上对应的 test-role 即可。

总结

根据以上的功能划分,我们很好的将一整个应用拆分成各个测试单元进行单元测试。需要注意的是,我们目前仅仅是对页面的可访问性进行测试,仅仅验证当用户进行各种操作,访问各个页面单元时页面是否会出错。并没有对页面的具体展示效果进行测试,这样会和页面的功能内容耦合起来,就需要单独的测试用例的编写了。

出处:http://985.so/aBWn         

             

最新课程通知

Golang 零基础入门课程

本课程为:网络班(腾讯课堂)

https://ke.qq.com/course/406096?tuin=6ceacb80

51reboot 运维前端课程正在火热招生和中,

8.21号开课

51reboot Devops 课程 九月下旬开课,

AWS中国区资深架构师带你领略云计算鼻祖的自动化架构

51reboot Python 实战课程 八月下旬开课,

想要学习的小伙伴可以扫码咨询c9c8cf3d73e34b853cfb2ec1525eb5ea.png

添加小助手WeChat:17812796384

64d27edb01d8f4b9d6a1ef4772da05e3.png

 

e56b5ed70a2a2d2eea391cd8c268eabd.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值