Puppteer 是 Google 推出的自动化工具,包含 Chromium 用于模拟用户侧操作,本文介绍如何 配合 Mocha 和 Chai 使用 Puppteer 开展自动化测试
资源链接
Puppteer Github 页面 Puppteer API 定义 Puppteer API 定义(中文版)
简介
Puppeteer 是 Chrome Developer Protocol 的上层封装。
将底层复杂的 CDP 协议封装为 Javascript 的 API,所以能实现代码模拟 chrome 操作。
对应用户操作
用 Puppteer 可以模拟用户侧的操作,内置的模型和用户操作 Chrome 的大致对应关系如下:
浏览器动作 | 实例化对象 |
---|---|
打开 Chrome 浏览器窗口 | browser 实例 |
浏览器 Tab | page 实例 |
如果使用 async/await 语法编写 Puppeteer 脚本,会大大简化代码,而且更为接近用户的行为,因为我们总是眼睛看到某个事件发生后,再驱动手去做下一个动作。
比如,用户眼睛看到浏览器窗口出现后,手找到地址栏,填入想要浏览的网址。用代码描述这个过程,大致是这样的:
page = await browser.newPage()
await page.goto(url)
配合 Mocha 和 Chai
Mocha 用来组织测试用例,Chai 用来实现断言
新建一个 package.json 如下
{
"name": "behavior_test",
"version": "1.0.0",
"description": "behavior test with puppeteer and mocha",
"scripts": {
"test": "mocha"
},
"dependencies": {
"puppeteer": "1.13.0",
"chai": "*",
"mocha": "^6.0.2"
}
}
执行 npm install
后,将 node_modules/.bin 的绝对路径 加入 Path 变量,方便全局执行 mocha,比如
PATH=/path/to/your/puppeteer/project/node_modules/.bin:$PATH
其中的路径仅仅是举例子,具体到每个机器是不一样的
第一个测试代码
在项目目录里新建一个 test
目录,然后在目录下新建
first.js
,内容如下:
/**
* @name first.js
* @desc 第一个 Puppeteer 脚本
*/
const puppeteer = require('puppeteer')
const expect = require('chai').expect
let browser, page
const url = 'https://www.baidu.com'
const width = 1600
const height = 900
const browserOption = {
headless: false,
ignoreHTTPSErrors: true,
slowMo: 100,
args: [
`--window-size=${width},${height}`
]
}
const viewport = {
width: width,
height: height
}
describe('百度页面测试', function() {
before(async function () {
this.timeout(5000);
browser = await puppeteer.launch(browserOption)
page = await browser.newPage()
await page.setViewport(viewport)
})
it('打开百度首页', async function () {
await page.goto(url)
logo = await page.waitForSelector('#lg')
expect(logo).to.exist
}).timeout(5000)
it('搜索关键字', async function () {
input = await page.waitForSelector('#kw')
await input.type('puppeteer')
btn = await page.waitForSelector('#su')
await Promise.all([
btn.click(),
page.waitForNavigation()
])
container = await page.waitForSelector('#container')
expect(container).to.exist
}).timeout(10000)
after(async function() {
await browser.close()
})
})
执行 mocha
后,应该能看到弹出 Chromium 窗口弹出,执行完后自动关闭,同时命令行里打出以下内容:
代码解读
上面代码的逐行解读如下:
describe('百度页面测试', function() {
describe 是测试集,第一个参数,是测试集的名称,将显示在命令行里。
before(async function () {
before 和 after 是 mocha 的一种钩子函数,当某些关键时间点触发执行
async 关键字用来声明该函数使用 async/await 的语法,对这对关键字的理解可以看下一篇 《Promise 概念的理解》
this.timeout(5000);
指定 before 函数的超时时间为5秒钟。由于启动 Chromium 所需时间往往大于默认的2秒钟,如果不指定超时,会导致错误。
browser = await puppeteer.launch(browserOption)
初始化 browser 实例,传递一些参数都是为了方便调试,具体如下:
- headless: false
关闭 headless 模式,打开 Chrome 实体窗口,方便观察整个过程
- ignoreHTTPSErrors: true
忽略 https 的报错,避免进入 chrome 的警告页面
- slowMo: 100
所有动作之间增加 100ms 的暂停间隔,自动化过程是很快的,增加间隔方便观察
- args: [
—window-size=${width},${height}
]
规定实体窗口的大小和视口大小一致,默认的窗口只有800x600,比实际可用的视口小
更为详细的参数配置,见这篇文章 《Puppteer 配置浏览器属性》
(Chromium Logo)
当 puppeteer.launch()
成功实例化后,将对象赋予 browser 变量
page = await browser.newPage()
newPage() 用来生成 page 实例,相当于 Chrome 浏览器中的 一个个 tab
await page.setViewport(viewport)
setViewport() 设置页面视口
it('打开百度首页', async function () {
it() 相当于一个测试用例,第一个参数用来描述用例的期望值,运行测试时会出现在命令行里;第二个参数是一个 async 函数
await page.goto(url)
goto() 将页面导航至指定的地址,页面加载完后,接着执行下一步
logo = await page.waitForSelector('#lg')
waitForSelector() 寻找 id 为 ’lg’ 的元素,如果找到后,赋值给 logo
expect(logo).to.exist
chai 模块的 expect 函数,断言 logo 元素存在
}).timeout(5000)
timeout() 指定该测试用例的超时时间,需要根据网速和网页大小调整
第二个 it() 里的函数都能望文生义,不需要太多解释,这一段需要特别解释:
await Promise.all([
btn.click(),
page.waitForNavigation()
])
这段代码的场景是处理点击触发页面跳转的通常写法。将点击事件和页面跳转包裹在一起,只有两件事情都完成后,整个Promise 才算完成。接下来的动作(比如寻找元素)都是在新页面里完成。
Promise 概念的理解可以看下一篇 Promise 概念的理解
如果您对本文有疑问或者寻求合作,欢迎 联系邮箱 。邮箱已到剪贴板
精彩评论
本站 是个人网站,采用 署名协议 CC-BY-NC 授权。
欢迎转载,请保留原文链接 https://www.lfhacks.com/tech/puppeteer-mocha-chai/ ,且不得用于商业用途。