小程序单元测试

测试工具集

小程序的运行环境比较特殊,不同于常见的浏览器环境,它采用的是双线程的架构。而在进行单元测试时,我们并不需要用到这样复杂的架构带来的利好,我们进行的是功能测试而无需苛求性能、安全等因素,因此微信小程序官方提供了一个测试工具集: miniprogram-simulate,以支持自定义组件在 nodejs 单线程中也能运行起来 。

架构图

使用流程

  1. 安装:miniprogram-simulate需结合jest测试框架一起使用。

jest官网:配置 Jest · Jest

miniprogram-simulate官网:miniprogram-simulate/tutorial.md at master · wechat-miniprogram/miniprogram-simulate · GitHub

         // 小程序工具集$ npm i --save-dev miniprogram-simulate

// Jest测试框架$ npm i --save-dev jest

        2. 添加测试脚本命令,在package.json中添加脚本 

 "scripts": {     "test": "jest"   },

        3 . 编写组件测试(演示小demo,更多用法请见上述官网)

a. 在项目新建test文件夹用于存放单元测试文件,创建index.test.js文件,下面就将在此文件编写测试demo。

const simulate = require('miniprogram-simulate')
​
test('components/index', () => {
 const id = simulate.load('/components/index') // 此处必须传入待测试组件绝对路径
 // const id = simulate.load(path.join(__dirname, './index')); // 可以视情况使用path
 const comp = simulate.render(id) // 渲染成自定义组件树实例
​
 const parent = document.createElement('parent-wrapper') // 创建父亲节点
 comp.attach(parent) // attach 到父亲节点上,此时会触发自定义组件的 attached 钩子
​
 const view = comp.querySelector('.index') // 获取子组件 view
 expect(view.dom.innerHTML).toBe('index.properties') // 测试渲染结果
 expect(window.getComputedStyle(view.dom).color).toBe('green') // 测试渲染结果
})

        b. 执行npm run test即可输出测试结果

进阶使用

1. 传入初始渲染 props

test('comp', () => {
    // 前略

    const comp = simulate.render(id, {
        propName: 'propValue',
    })
})

2. 获取数据

test('comp', () => {
    // 前略

    // 判断组件数据
    expect(comp.data).toEqual({
        a: 111,
    })
})

3. 更新数据

test('comp', () => {
    // 前略

    // 更新组件数据
    comp.setData({
        a: 123,
    })
})

4. 获取子组件

test('comp', () => {
    // 前略

    const childComp = comp.querySelector('#child-id')
    expect(childComp.dom.innerHTML).toBe('<div>child</div>')
})

5. 获取子组件列表

test('comp', () => {
    // 前略

    const childrenComp = comp.querySelectorAll('.child-item')
    expect(childrenComp.length).toBe(3)
})

6. 触发事件

test('comp', () => {
    // 前略

    comp.dispatchEvent('touchstart') // 触发组件的 touchstart 事件
    childComp.dispatchEvent('tap') // 触发子组件的 tap 事件
})

7. 触发生命周期

test('comp', () => {
    // 前略

    comp.triggerLifeTime('ready') // 触发组件的 ready 生命周期
    childComp.triggerLifeTime('moved') // 触发子组件的 moved 生命周期
})

8. 获取组件 this

test('comp', () => {
    // 前略

    const that = comp.instance // 注意,此处并不是返回 comp,comp 是在组件实例上再封装了一层的对象,而这里返回的是组件实例,即组件方法定义里的 this

    that.data // 获取组件的 data 对象,这里和 comp.data 拿到的对象是一样的
    that.xxx() // 调用组件 methods 定义段里定义的方法
})

覆盖率

编写单测后,最重要的衡量指标则是单测的覆盖率了,覆盖率指标包含:

1. 行覆盖率(line coverage):是否每一行都执行了?

2. 函数覆盖率(function coverage):是否每个函数都调用了?

3. 分支覆盖率(branch coverage):是否每个if代码块都执行了?

4. 语句覆盖率(statement coverage):是否每个语句都执行了?

覆盖率报告

在package.json中使用"jest --coverage"即可生成覆盖率测试报告,执行脚本后会在控制台输出对应文件的函数个数、行数等文件详情以及未覆盖的函数;同时会在项目根目录下生成coverage文件夹,在浏览器打开index.html即可查看友好的图示覆盖率详情。

踩坑日志

  1. 小程序中不可避免的会使用大量的微信官方api,如wx.xxx,但是此测试环境是运行在 nodejs 上,不存在这些接口的底层实现。因此开发者在写测试用例时对于自己将要使用的接口进行模拟。

简单的例子:如下,若小程序ready生命周期中使用了 wx.getSystemSetting ,则需要在单测中对getSystemSetting进行期望结果的输出模拟。

  wx.getSystemSetting = function () {
    return {};
  };
  comp.triggerLifeTime('ready'); // 触发组件的 ready 生命周期

        2. 小程序官方api非挂载在wx上的,如getCurrentPages等,需要挂载在global上,与开发者沟通后上述第一点处理方法类似:

issuse地址:使用comp.triggerLifeTime('ready')或者其他功能时,微信官方api(非wx.xxx)无法成功调用 · Issue #103 · wechat-miniprogram/miniprogram-simulate · GitHub

global.getCurrentPages = function (){
	return [];
}
comp.triggerLifeTime('ready'); // 触发组件的 ready 生命周期

        3. 未完待续...

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值