小程序自动化介绍
小程序自动化 SDK 为开发者提供了一套通过外部脚本操控小程序的方案,从而实现小程序自动化测试的目的。
小程序自动化特性
通过该 SDK,你可以做到以下事情:
- 控制小程序跳转到指定页面
- 获取小程序页面数据
- 获取小程序页面元素状态
- 触发小程序元素绑定事件
- 往 AppService 注入代码片段
- 调用 wx 对象上任意接口
运行环境
这里要注意一下,一定要满足以下条件小程序自动化SDK才能正常运行
- 安装Node,版本大于8.0
- 基础库版本为
2.7.3
及以上 - 开发者工具版本为 1.02.1907232 及以上
安装SDK
npm i miniprogram-automator --save-dev
使用小程序自动化SDK
小程序自动化SDK为我们提供了Automator,MIniProgram,Page,Element四个模块的API功能,分为功能为
- Automator 模块提供了启动及连接开发者工具的方法
- MiniProgram 模块提供了控制小程序的方法
- Page 模块提供了控制小程序页面的方法
- Element 模块提供了控制小程序页面元素的方法
具体请参考小程序官方文档:小程序文档
使用JEST测试框架
小程序自动化 SDK 本身不提供测试框架。这意味着你可以将它与市面上流行的任意 Node.js 测试框架结合使用,以此来达到编写小程序测试用例的目的。
JEST具体请查阅JEST中文文档
在运行测试脚本之前需要把你的微信开发工具关闭才可以启动,否则脚本不会正常启动
连接并启动开发工具,这里有一个小坑,官方文档中给出的示例是这样的
const automator = require('miniprogram-automator')
describe('index', () => {
let miniProgram
let page
beforeAll(async () => {
miniProgram = await automator.launch({
projectPath: 'path/to/miniprogram-demo'
})
page = await miniProgram.reLaunch('/page/component/index')
await page.waitFor(500)
}, 30000)
afterAll(async () => {
await miniProgram.close()
})
})
这里automator,launch中配置的是你开发工具的路径以及你的项目路径,如果你的开发路径是默认选择的话可以不配
下面是文档截图:
这里按照文档的格式的话会打不开你的小程序项目,我尝试了半天最后按照下面这个路径格式打开的项目
describe('高考填报模块', () => { //describe : 创建一个将几个相关测试组合在一起的模块
let miniProgram
let page
beforeAll(async () => { //运行此文件中的任何测试之前的功能
miniProgram = await automator.launch({
projectPath: 'C:\\project\\newWechat\\wechatMini'
})
page = await miniProgram.reLaunch('/pages/index/index')
await page.waitFor(500)
}, 300000)
afterAll(async () => { //在所有测试结束之后
await miniProgram.close() //断开与小程序运行时的连接并关闭项目窗口。
})
})
启动了项目以后就可以按照小程序的自动化文档结合JEST文档来写测试代码了,这里贴一下
it('list', async () => {
const lists = await page.$$('.kind-list-item')
expect(lists.length).toBe(8)
const list = await lists[0].$('.kind-list-item-hd')
expect(await list.text()).toBe('视图容器')
})
运行测试代码,在命令行输入
jest 文件名.js
使用小程序自动化的采坑总结
1. 运行jest index.spec.js时报错
报错信息为
Failed to launch wechat web devTools, please make sure http port is open
我使用的版本:
- node 版本为12.13.1
- 基础库版本为2.10.0
- 开发者工具版本为1.03.2005140
解决办法总结 :
- 开发工具版本问题
- 安装
Node.js
并且版本大于 8.0 - 基础库版本为
2.7.3
及以上 - 开发者工具版本为
1.02.1907232
及以上
查看一下是否满足以上3个条件
2.运行时关闭微信开发者工具
- 定义项目路径时出错
- 检查微信开发者工具是否为默认路径,
- Mac:/Applications/wechatwebdevtools.app/Contents/MacOS/cli
- Win:C:/Program Files (x86)/Tencent/微信web开发者工具/cli.bat
如果不是则需要配置,我的电脑是默认路径所以没有出现问题
- 检查项目路径是否正确
我是这里出现的问题,一开始我使用的路径是这样
miniProgram = await automator.launch({
projectPath: 'C:/project/newWechat/wechatMini/wechatproject'
})
这样每次只打开了微信开发者工具就是打不开项目,后来我换成了下面这样的写法
miniProgram = await automator.launch({
projectPath: 'C:\\project\\newWechat\\wechatMini\\wechatproject'
})
还有打开的页面,要配置为绝对路径的页面
page = await miniProgram.reLaunch('/pages/index/index')
2. 给input加值
name.trigger("input", {"detail": {"value": "测试"}}) ---- 这个 trigger 触发控件支持的事件时,把 bind 去掉就可以了
self.page.call_method("bindKeyInput", {"detail": {"value": "测试"}}) ---- 这个通过触发控件input 事件绑定的函数
3. 添加路径时一定要是绝对路径
let miniProgram
let page
beforeAll(async () => { //运行此文件中的任何测试之前的功能
miniProgram = await automator.launch({
projectPath: 'C:\\project\\newWechat\\wechatMini'
})
page = await miniProgram.reLaunch('/pages/index/index')
await page.waitFor(500)
}, 300000)
如果不加"/"就会报错
pages/index/pages/index/indexjs
4. 获取自定义组件时的坑
获取自定义组件中的元素时返回的都是undefind,需要先打印一下父节点的wxml,会发现组件的雷鸣都加上了组件名前缀,使用这个类名就可以获取到自定义组件中的元素了
获取页面中的组件只能采用page.$()或page.$$()方法,经尝试选择器仅支持组件名和类名。无法直接获取自定义组件内部组件元素,需要在类名前增加前缀。实际项目的页面中大量使用自定义组件,对于自定义组件内部的结构判断非常不方便,只能通过wxml()
方法将自定义组件内部结构打印出来才能确认内部的子组件的实际情况。且无法调用自定义组件内部的方法。
5. 获取微信wx原生组件,如:wx.showModule
小程序自动化不支持获取到wx的原生方法,但是可以通过miniProgram.mockWxMethod()方法模拟wx原生组件。
//示例代码
automator.launch().then(async miniProgram => {
await miniProgram.mockWxMethod('showModal', {
confirm: true,
cancel: false
})
await miniProgram.mockWxMethod(
'getStorageSync',
function(key, defVal) {
if (key === 'name') return 'redhoodsu'
if (key === 'sex') return 'male'
return defVal
},
'unknown',
)
// 调用 wx.getStorageSync('name') 返回 'redhoodsu'
// 更改 getSystemInfo 中的 platform 字段
await miniProgram.mockWxMethod(
'getSystemInfo',
function(obj, platform) {
return new Promise(resolve => {
// origin 指向原始方法
this.origin({
success(res) {
res.platform = platform
resolve(res)
},
})
})
},
'test',
)
})
总结
前面就是我使用小程序SDK+JEST的一些心得,开发中有新的收获和采坑总结我也会记录在这里。