曾几何时,大家还不知道什么是小程序,它到底能干些什么,跟App有啥区别,跟H5又有啥区别,但是最近几年,依托于腾讯这颗大树,已经迅速建立起了小程序良好的生态体系,同时也因为APP市场的饱满,以及其开发和推广成本高等问题,目前几乎所有的互联网公司的业务都用起了小程序,而且页面也越来越复杂,涉及的业务场景也越来越多,小程序已经是IT互联网领域一个举足轻重的属性了。
为了应对小程序如火如荼的发展,腾讯在今年5月底推出了miniprogram-automator来支持小程序的自动化测试,本文也主要是基于此项技术来做介绍,让大家对小程序自动化有个初步的了解。
在腾讯推出此项技术之前,其实小程序的自动化测试已经有所开展了,主要有以下几种方式:
1. 通过APP自动化的工具appium来实现的
2. 通过Airtest来实现
3. 通过FAutoTest来实现
这些方法大同小异,基本上都属于黑盒自动化方案。此处不做具体介绍,大家可以自行查阅。
Miniprogram-automator是腾讯自研的一套小程序自动化sdk,原理跟大家熟知的自动化测试框架selenium webdriver类似,只是操作的目标不同而已。
运行环境
SDK安装
npm i miniprogram-automator --save-dev
框架支持编写语言
目前此框架仅支持通过JAVAscript来书写自动化测试用例。
简单应用
代码片段
const automator = require('miniprogram-automator') const miniProgram = automator.launch({ cliPath: '/Applications/wechatwebdevtools.app/Contents/macOS/cli', projectPath: '/Users/user/Desktop/miniprogram-quickstart-master/miniprogram-quickstart-master', }).then(async miniProgram => { const page = await miniProgram.reLaunch('/pages/index/index') await page.waitFor(500) const element = await page.$('.user-motto') console.log(await element.text()) await miniProgram.close() })
运行用例
将上述代码保存到test.js中,然后运行命令如下:
node test.js
代码讲解
const automator = require('miniprogram-automator')
首先需要引入miniprogram-automator自动化包,此处需要注意的是代码文件和miniprogram-automator包的地址的路径问题,否则会出现类似Cannot find module 'miniprogram-automator' 这样的问题出现。
const miniProgram = automator.launch({ cliPath: '/Applications/wechatwebdevtools.app/Contents/MacOS/cli', projectPath: '/Users/user/Desktop/miniprogram-quickstart-master/miniprogram-quickstart-master', }).then(async miniProgram => { })
此块创建了miniProgram的实例,该模块提供了控制小程序的方法automator.launch用来启动并连接微信开发者工具。
cliPath: 工具cli位置,默认路径是/Applications/wechatdevtools.app/Contents/MacOS/cli
projectPath: 项目文件路径
此处是通过cli命令行来启动微信开发者工具,要达到此目的,需要注意以下前提条件:
1、确保工具安全设置中已开启 CLI/HTTP 调用功能。
开发者工具菜单中的设置->安全设置->服务端口
2、开启小程序自动化功能
cli --auto <project_root> --auto-port <port> const page = await miniProgram.reLaunch('/pages/index/index')
此处是通过调用miniProgram提供的relaunch方法创建了一个page的实例,page模块提供了控制小程序页面的方法,relanch方法会关闭所有的页面,打开到应用内指定的页面。里面中的参数是页面的路径,此路径可以从app.json文件中获取到。
await page.waitFor(500)
此处是调用page的waitFor方法,等待直到指定条件成立,方法的参数是number类型,该参数会被当成超时时长,当经过指定时间后,结束等待。这块属于隐式等待,如果想进行显示等待的话,可以传入string或是function类型。
const element = await page.$('.user-motto')
此处是调用page模块的$方法,用来获取页面元素,参数是元素的选择器字符串,定位element元素时可以在微信开发者工具调试器中wxml处进行调试。
await miniProgram.close()
此处调用miniProgram模块的close方法关闭与小程序运行的连接并且关闭项目窗口。
Miniprogram-automator 这个仅仅是小程序自动化的sdk,说直白些,仅提供了一些API,并不是真正意义上的测试框架,这意味着上述的代码仅仅是JavaScript的代码片段,而非真正意义上的自动化测试用例,要达到真正书写自动化测试用例,需要一款测试框架,该框架可以是市面上任意一款node.js的javascript框架。miniprogram-automator负责操作小程序页面的信息,测试框架负责组织和断言。
测试框架选取与安装
此处使用时下比较流行的facebook出品的一款测试框架Jest,该框架集成了众多框架的功能。
npm i jest -g
简单应用
代码片段
const automator = require('miniprogram-automator') describe('小程序自动化测试初体验', () => { let miniProgram beforeAll(async () => { miniProgram = await automator.launch({ cliPath: '/Applications/wechatwebdevtools.app/Contents/MacOS/cli', projectPath: '/Users/user/Desktop/miniprogram-quickstart-master/miniprogram-quickstart-master', }) }, 30000) it('测试微信用户座右铭是hello world', async () => { const page = await miniProgram.reLaunch('/pages/index/index') const user_motto = await page.$('.user-motto') expect(await user_motto.text()).toBe('Hello World') }) afterAll(async () => { await miniProgram.close() }) })
运行用例
将上述代码保存到quickstart.test.js中,然后运行命令如下:
jest quickstart.test.js
测试结果如下
代码讲解
此处仅讲解与纯miniprogram-automator模式不一样的代码部分。
describe('小程序自动化测试初体验', () => { let miniProgram beforeAll(async () => { miniProgram = await automator.launch({ cliPath: '/Applications/wechatwebdevtools.app/Contents/MacOS/cli', projectPath: '/Users/user/Desktop/miniprogram-quickstart-master/miniprogram-quickstart-master', }) }, 30000)
因为Jest集成了Mocha,chai,jsdom,sinon等功能,所以这些框架的语法都可以在Jest应用,describe此处就是起test suite的意义。
beforeAll属于测试生命周期API的一种,用在所有测试用例开始前执行。此方法可以进行一些测试初始化的操作。
30000 属于设置的Jest的超时时间,因为工具项目窗口启动初次编译需要一定时长,Jest 默认 5 秒超时太短,所以需要修改如此。
it('测试微信用户座右铭是hello world', async () => { const page = await miniProgram.reLaunch('/pages/index/index') const user_motto = await page.$('.user-motto') expect(await user_motto.text()).toBe('Hello World') })
此处属于具体的测试用例,可以用it,也可以用test关键字。
toBe是matcher函数,使用expect和”matcher”函数结合验证属于具体的断言部分。判断实际得到的结果跟预期结果是否一致。
afterAll(async () => { await miniProgram.close() })
afterAll也属于测试生命周期API的一种,用来在所有用例执行完毕后执行,此处可以进行一些清理收尾工作。
注:本文是针对小程序快速启动模板项目https://github.com/wechat-miniprogram/miniprogram-quickstart 做的自动化测试。