单元测试
在组件开发完成并发布之前,需要对组件进行单元测试,单元测试是使用断言的方式判断实际的输出与预测的输出是否相同,目的是发现可能存在的问题;组件的单元测试是指使用单元测试工具对组件的各种状态及行为进行测试,确保组件发布后在使用过程中不会出现错误。
Vue组件的单元测试
-
组件的单元测试有很多好处:
- 提供描述组件行为的文档
- 节省手动测试的时间
- 减少研发新特性时产生的 bug
- 改进设计
- 促进重构
-
用 Jest 测试单文件组件
官方文档
首先需要安装 Jest 和 Vue Test Utils
yarn add jest @vue/test-utils -D -W
然后需要在
package.json
中定义一个单元测试的脚本// package.json { "scripts": { "test": "jest" // 修改test为jest } }
为了告诉 Jest 如何处理
*.vue
文件,需要安装和配置vue-jest
预处理器:yarn add vue-jest -D -W
创建jext.config.js配置文件
module.exports = { "testMatch": ["**/__tests__/**/*.[jt]s?(x)"], "moduleFileExtensions": [ "js", "json", // 告诉 Jest 处理 `*.vue` 文件 "vue" ], "transform": { // 用 `vue-jest` 处理 `*.vue` 文件 ".*\\.(vue)$": "vue-jest", // 用 `babel-jest` 处理 js ".*\\.(js)$": "babel-jest" } }
需要安装
babel-jest
处理es6语法yarn add babel-jest -D -W
babel配置文件
// babel.config.js module.exports = { presets: [ [ '@babel/preset-env' ] ] }
Babel 的桥接
yarn add babel-core@bridge -D -W
-
Jest常用API
中文文档
-
全局函数
describe(name, fn) 把相关测试组合在一起
test(name, fn) 测试方法
expect(value) 断言
-
匹配器
toBe(value) 判断值是否相等
toEqual(obj) 判断对象是否相等
toContain(value) 判断数组或字符串是否包含
-
快照
toMatchSnapshot()
-
-
vue-jest常用API
中文文档
- mount() 创建一个包含被挂载和渲染的Vue组件的Wrapper
- Wrapper
- vm wrapper包裹的组件实例
- props() 返回Vue实例选项中的props对象
- html() 组件生成的HTML标签
- find() 通过选择器返回匹配的组件中的DOM元素
- trigger() 触发DOM原生事件,自定义事件wrapper.vm.$emit()
- ...
-
创建
packages/input/__tests__/input.test.js
文件@vue/test-utils提供API用于挂载组件,Jest不需要导入因为测试文件是被jest加载执行的
import input from '../src/input.vue' import { mount } from '@vue/test-utils' // 创建代码块 将input相关测试都添加到这里 describe('wang-input', () => { test('input-text', () => { // 挂载组件 只是内存中的挂载 返回一个包裹器 const wrapper = mount(input) // 测试生成的html中是否包含type=text expect(wrapper.html()).toContain('input type="text"') }) })
-
使用
yarn test
测试
-
添加更多测试
... test('input-password', () => { const wrapper = mount(input, { propsData: { type: 'password', }, }) expect(wrapper.html()).toContain('input type="password"') }) test('input-password', () => { const wrapper = mount(input, { propsData: { type: 'password', value: 'admin', }, }) expect(wrapper.props('value')).toBe('admin') }) // 快照 test('input-snapshot', () => { const wrapper = mount(input, { propsData: { type: 'password', value: 'admin', }, }) // 快照 第一次运行会将wrapper.vm.$el的内容存储在./__snapshots__/input.test.js.snap中 expect(wrapper.vm.$el).toMatchSnapshot() }) ...
如果以后生成的快照和第一次生成的不同,会测试失败,如下所示:
可以通过yarn test -u
删除旧的快照文件,并重新生成
Rollup打包
-
特点
- Rollup是一个模块打包器
- Rollup支持Tree-shaking
- 打包结果比webpack小
- 开发框架/组件库使用Rollup更合适,如Vue、React等
-
安装
- Rollup
- rollup-plugin-terser 对代码进行压缩
- [email protected] 将单文件组件编译成js代码,最新版本适用于vue3.x,内部需要使用到vue-template-compiler
- vue-template-compiler
-
设置Rollup配置文件
import { terser } from 'rollup-plugin-terser' import vue from 'rollup-plugin-vue' module.exports = [ { input: 'index.js', output: [ { file: 'dist/index.js', format: 'es' } ], plugins: [ vue({ // Dynamically inject css as a