惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
D
DataBreaches.Net
博客园 - 三生石上(FineUI控件)
博客园_首页
T
Tailwind CSS Blog
美团技术团队
Hugging Face - Blog
Hugging Face - Blog
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
云风的 BLOG
云风的 BLOG
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 聂微东
S
SegmentFault 最新的问题
小众软件
小众软件
酷 壳 – CoolShell
酷 壳 – CoolShell
N
Netflix TechBlog - Medium
Jina AI
Jina AI
WordPress大学
WordPress大学
U
Unit 42
J
Java Code Geeks
Blog — PlanetScale
Blog — PlanetScale
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog

晚花行乐

马克卡尼在2026年达沃斯论坛上的讲话(阅读材料) | 晚花行乐 鸡娃如何用力才是恰到好处 | 晚花行乐 读万卷书,行万里路的辩证关系 | 晚花行乐 反对培训机构掐尖招生 | 晚花行乐 小泽和建国会谈最后10分钟全文(阅读材料) | 晚花行乐 来看看 DeepSeek 怎么鸡娃 | 晚花行乐 谈谈基本功 | 晚花行乐 惠普 ProDesk SFF PC 各系列参数对比 | 晚花行乐 解决瘦客户机上安装 Debian 12 启动失败问题 | 晚花行乐 意拾喻言:老外写的文言文 | 晚花行乐 笠翁对韵中的典故(十三元) | 晚花行乐 谈谈中考取消四小门 | 晚花行乐 亚马逊云科技产品免费试用攻略(3) - 对象存储服务 | 晚花行乐 在 Windows 10 LTSC 版本上安装 WSL2 | 晚花行乐 Debian 12 的常用配置项 | 晚花行乐 在 Debian 12 上安装 Nvidia 显卡驱动程序 | 晚花行乐 解决 Debian 12 关机失败问题 | 晚花行乐 解决 VS Code 自动更新版本后卡在连接界面 | 晚花行乐 观看巴黎奥运会有感 | 晚花行乐 在 Windows10 上安装惠普旧打印机驱动程序 | 晚花行乐 欢迎关注公众号:晚花行乐 | 晚花行乐 如何编写拼写检查器 | 晚花行乐 亚马逊云科技产品免费试用攻略(2) - 云服务器 | 晚花行乐 Pandas 中 axis 参数的理解(附实例) | 晚花行乐 我打算命个名,叫什么什么 Manager | 晚花行乐 上海武康路历史建筑一览 | 晚花行乐 Python 实现简单的数学表达式解析并处理 | 晚花行乐 观看马拉松的感悟 | 晚花行乐 Python 保存 Cookies 到文件并再次读取 | 晚花行乐 如何为 Hugo 静态网站添加评论功能 | 晚花行乐
Puppeteer 实现 web 自动测试 | 晚花行乐
2019-04-17 · via 晚花行乐

Puppteer 是 Google 推出的自动化工具,包含 Chromium 用于模拟用户侧操作,本文介绍如何 配合 Mocha 和 Chai 使用 Puppteer 开展自动化测试

Puppteer Github 页面 Puppteer API 定义 Puppteer API 定义(中文版)

简介

Puppeteer 是 Chrome Developer Protocol 的上层封装。

将底层复杂的 CDP 协议封装为 Javascript 的 API,所以能实现代码模拟 chrome 操作。

对应用户操作

用 Puppteer 可以模拟用户侧的操作,内置的模型和用户操作 Chrome 的大致对应关系如下:

浏览器动作实例化对象
打开 Chrome 浏览器窗口browser 实例
浏览器 Tabpage 实例

如果使用 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 概念的理解

各位读后有什么想法,请在下方留言吧!如果对本文有疑问或者寻求合作,欢迎 联系邮箱邮箱已到剪贴板

精彩评论