最近在看自动化测试方面的内容,了解到现在比较流行的方案是python+selenium+unittest来做自动化测试。
之前有使用过puppeteer来编写爬虫,就在想使用puppeteer来做测试是否可行,在找资料时看到这篇文章感觉比较适合入门,就尝试把它翻译了一下。
译文和原文相比主要把一些无关内容删去了,不过主旨还是一致:通过一些小的demo来窥探puppeteer测试的风采.
原文:https://medium.com/@ankit_m/ui-testing-with-puppeteer-and-mocha-part-1-getting-started-b141b2f9e21
译文:https://lonhon.top/2018/09/27/Puppeteer-mocha-ui-test/
本文由个人结合实际情况翻译,与原文有差别属正常,文中亦做相应标注.
1.前言
每个搭开发过webapp的开发人员一定知道每次测试新功能的痛苦:你只是修改了一个独立的功能模块,却有可能影响整个项目运行,你不得不考虑出bug的后果。
为了防止出现重大bug,你需要花费大量时间去跑业务流程,但是总会漏网之鱼,这绝不是一个可靠的测试方法。摆脱这种费时费力不讨好的唯一方式就是编写测试用例来进行验证即UI测试
本文尝试用puppeteer和mocha来进行UI测试,需要你掌握一些基础Javascript知识。
2. 工具库
2.1 Mocha
Mocha是一个js测试框架,它提供了很多api来组织测试用例,比如descripe,it,before等,同时也提供命令行和编程的方式来执行测试。
2.2 Chai
单独使用Mocha对我们意义不大,我们还需要一个支持它的断言库来实际进行测试,本文选择ChaiJS作为断言库,也可以选择其它库比如expect.js,should.js等
2.3 Puppeteer
Puppeteer是一个headless的chrome浏览器库,最初基于Chrome 59版本(Windows下为Chrome 60)。它提供了许多api来方便的访问和操纵DOM、cookie、ajax等。
我们将使用这些api来查看页面的UI元素,并在它们上运行断言来检查是否正确符合预期。
3. 基础用法
首先需要安装node.js,然后我们创建一个项目目录 d:\puppeteer-mocha\ 。
个人建议使用nvm来管理node版本,本文使用[email protected] [email protected]。
1 | d: |
上面模块安装时都指定了版本,你可以跳过这个步骤;这里还用到http-server开启一个简单的web服务器,如果已有,也可跳过。
现在需要做的:
- 添加test目录放测试文件
- 添加src目录放网站
- 添加npm scripts来开启服务器和进行测试
正式开始之前,我们先创建一个index.html文件作为测试对象:1
2
3
4
5
6
7
8
9
10
<html>
<head>
<title>Puppeteer Mocha</title>
</head>
<body>
<h1>Page Title</h1>
<p class='main-content'>Some paragraph text</p>
</body>
</html>
接下来添加两个npm脚本到package.json中,test脚本告知mocha需要执行的测试文件在test目录,–recursive参数表示运行子目录里的测试文件。
server脚本会启动服务器并运行在 http://127.0.0.1:8080
1 | "scripts": { |
最后,我们来创建一个简单的测试来检查环境是否正常,添加 sample.spec.js 文件,代码如下:1
2
3
4
5
6
7const { expect } = require('chai');
describe('sample test', function () {
it('should work', function () {
expect(true).to.be.true;
});
});
现在我们运行 npm test 试一下,正常的话会显示如下内容:1
2sample test
✓ should work
ok,现在我们结合puppeteer进行测试。
4. 整合Puppeteer
相较于每个测试单独开启新标签、运行测试、然后关闭页面,我们肯定更希望在一个页面下进行测试,并且复用该页面来进行所有测试。
这需要在 test/root.js 中进行设置,把在测试中使用需要的变量导出。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28const puppeteer = require('puppeteer');
const { expect } = require('chai');
const b = global.browser
const e = global.expect
const globalVariables = {
browser: b,
expect: e
}
// puppeteer options
const opts = {
headless: false,
slowMo: 100,
timeout: 10000
};
// expose variables
before (async function () {
global.expect = expect;
global.browser = await puppeteer.launch(opts);
});
// close browser and reset global variables
after (function () {
browser.close();
global.browser = globalVariables.browser;
global.expect = globalVariables.expect;
});
译注:上述代码中作者原本使用到lodash.pick方法,为减少安装,译文已将其转换。
before方法用于准备所有测试用例需要的browser和expect,它在测试之前运行一次并赋值给global.browser,就不用在每个测试用例里重复运行了。
当测试全部结束后,after方法会清理全局变量。
译注:global类似页面中的window对象,可全局调用.
需要特别注意的是puppeteer.launch 和 opts,launch启动了一个chrome浏览器,其配置如下:
- headless: false 是否开启无页面浏览器,这里是不开启
- 每个操作放慢100ms运行,适用于想看到所有运行过程
- 设置超时时间为10s
现在我们来调整一下 npm srcipt1
2"scripts": {
"test": "mocha test/root.js --recursive test",
接下来更新一下 test/sample.spec.js 文件,修改为测试browser的版本判断是否可用:1
2
3
4
5
6describe('sample test', function () {
it('should work', async function () {
console.log(await browser.version());
expect(true).to.be.true;
});
});
再次运行 npm test,不出意外你会看到以下输出:1
2
3sample test
Chrome/64.0.3264.0
✓ should work (103ms)
5. 第一个UI测试用例
通过以上,我们将所需要的准备工作已经搭好,接下来开始正式UI测试。
首先,我们测试以下3件事情:
- 页面title是“Puppeteer Mocha” (title标签)
- 页面内容标题是“Page Title” (H1)
- 页面包含一个样式为main-content的元素
Puppeteer有很多类构造器,比如Page,Frame,Request等,这些类都提供了相应的方法来查看页面和交互。
一般的工作流程是打开页面,等待选择器选择dom,然后验证内容,下面是基础它们的一些简单用法示例:
1 | // test/sample.spec.js |
在这个测试用例中我们做了好几件事,现在一一分析。
首先我们新建了一个页面导航至 http://localhost:8080,并将该页面赋值给变量page,
page在descript函数块里声明,里面的it都可以访问,这样就可以分割多个测试点,便于阅读。
译注: 建议把单个文件即 describe 想成一个完整功能测试,里面包含多个功能点即it的测试。
第一个it测试点是检查页面title是否是“Puppeteer Mocha”
第二个it是检查页面内容标题。page.$eval方法接受两个参数:selector和pageFunction,它先在浏览器环境下运行dom选择器document.querySelector并且将该dom作为pageFunction的参数。在这个用例中,我们最终返回了h1标签的文本并赋值给heading,然后对其进行判断。
第三个it检查页面中是否存在一个样式含main-content的元素,page.$$方法只接受选择器作为参数,它先执行document.querySelectorAll查找页面中所有样式含main-content的dom,返回值是一个数组,当length为1时表示通过测试。
6. 结语
本文只用到puppeteer的冰山一角,只为让你体验一下UI测试的魅力。在后续的文章中,我们将深入研究复杂的web页面和交互。
译注:这篇文章发布于2017.6,至今没有part2 应该是太监了…