最近折腾了单测,体会比较多,将思考、总结记录在这里,留作念想。
开篇
单测这件事情,感觉不是佛系的,要分场合,项目里有些复杂的utils、工具库、组件库是要有单测支撑的。
提倡单测的理由如下:
- 写代码之前先写用例case,可以让我们好好设计接口、模块、明确数据流向和上下游的关系
- 增强提测、上线质量
业务组件添加单测是锦上添花的事情,而且,学点新的知识有什么不好呢。单测的框架有不少,今天看看vue-test-utils,它是vue组件的官方测试库,内部使用了Facebook推出的Jest测试框架
官方文档:
https://lmiller1990.github.io/vue-testing-handbook/zh-CN/
https://jestjs.io/zh-Hans/docs/getting-started
安装开发环境
vue-cli配套插件@vue/cli-plugin-unit-jest, @vue/test-utils等可提供jest环境,依照项目实际情况修改jest配置
module.exports = {
// 哪些文件是要进行测试的
testMatch: [
'**/tests/**/*.spec.js',
],
// 预置,是解析的意思???
preset: '@vue/cli-plugin-unit-jest',
// ....等
}
scripts: {
"unit": "vue-cli-service test:unit",
"unit:dev": "vue-cli-service test:unit --watchAll",
}
还有vscode的神辅助插件
- Jest
对于整个项目的文件提供基本测试条件,如项目开启就自动监听变化,如果觉着造成不必要的浪费,可以手动关掉
- Jest Runner
方便我们测试和调试单个文件,Jest Runner使用的调试工具就是VScode的调试,所以启动的都是node环境,适当的时候要修改下babel.config.js的配置,否则会报错,比如不识别import等
至于为何运行npm run unit就不会报错,我猜测可能因为vue的sever服务帮我们做了一步转换吧
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
]
{
// jest debug配置
"jestrunner.debugOptions": {
"args": ["--no-cache"],
"sourcemaps": "inline",
"disableOptimisticBPs": true
},
// 不允许启动就开启单测监听模式
"jest.autoRun": "false",
"jestrunner.jestPath": "node_modules/jest/bin/jest.js",
"jestrunner.jestCommand": "npm run unit --",
}
// 具体关于这个写法(究竟叫什么名字)请调出插件的具体信息
具体的测试用例
下面以2个具体的例子来说明,一个是简单一些的util api测试,一个是公共组件的组件测试。
单测具体有两部分组成:
import { isNumber } from './util.js'
describe('test isNumber', () => {
test('是一个数字', () => {
expect(isNumber(8)).toBe(true);
})
// test vs it
it('ccc', () => {
})
})
在一个组件里面如果涉及到api请求、vuex store、vue router、等都有解决方案,可以通过mock创造你想要的绝大多数功能。
其中以mock api为例:
import request from './request.js'
// jest.mock('./request.js'); 就可以直接mock函数
// 其中request调用axios,是自己封装的一个请求库
<button @click="submit">提交</button>
function submit() {
request({
url: 'xxx',
data: {}
})
}
注意事项
expect(运行结果).toBe(期望的结果)
常见的断言方法:
expect({}).toBe({}) //判断两个对象是否相等
expect().not.toBe()
expect().toEqual() // 判断引用对象是否相等
expect(n).toBeNull(); //判断是否为null
expect(n).toBeUndefined(); //判断是否为undefined
expect(n).toBeDefined(); //判断结果与toBeUndefined相反
expect(n).toBeTruthy(); //判断结果为true
expect(n).toBeFalsy(); //判断结果为false
expect(value).toBeGreaterThan(3); //大于3
expect(value).toBeGreaterThanOrEqual(3.5); //大于等于3.5
expect(value).toBeLessThan(5); //小于5
expect(value).toBeLessThanOrEqual(4.5); //小于等于4.5
expect(value).toBeCloseTo(0.3); // 浮点数判断相等
expect('Christoph').toMatch(/stop/); //正则表达式判断
expect(['one','two']).toContain('one'); //不解释
jest的实现原理是什么呢?
敬请期待