最近折腾了单测,体会比较多,将思考、总结记录在这里,留作念想。
开篇
单测这件事情,感觉不是佛系的,要分场合,项目里有些复杂的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 itit('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(); //判断是否为nullexpect(n).toBeUndefined(); //判断是否为undefinedexpect(n).toBeDefined(); //判断结果与toBeUndefined相反expect(n).toBeTruthy(); //判断结果为trueexpect(n).toBeFalsy(); //判断结果为falseexpect(value).toBeGreaterThan(3); //大于3expect(value).toBeGreaterThanOrEqual(3.5); //大于等于3.5expect(value).toBeLessThan(5); //小于5expect(value).toBeLessThanOrEqual(4.5); //小于等于4.5expect(value).toBeCloseTo(0.3); // 浮点数判断相等expect('Christoph').toMatch(/stop/); //正则表达式判断expect(['one','two']).toContain('one'); //不解释
jest的实现原理是什么呢?
敬请期待
