安装
jest的使用依赖nodejs,要先行安装
若使用vue-cli还可以用vue add将其作为vue插件(cli-plugin-unit-jest)使用,即下方第二种方式
方式一
npm install --save-dev jest
方式二
vue add @vue/cli-plugin-unit-jest
不过vue-cli项目创建时就会提供选择,其中勾上jest就会自行配置
项目中使用的就是这种方式,因此本文讲解这种方式,但具体测试写法一致,可作参考
基础讲解
若使用vue-cli且以方式二安装,那么创建项目后目录结构应形如:
其中 /tests/unit 存放的即是测试代码,目前自带一个板子:example.spec.js
打开上述文件,里面内容应是:
import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message'
const wrapper = shallowMount(HelloWorld, {
propsData: { msg }
})
expect(wrapper.text()).toMatch(msg)
})
})
shallowMount
挂载一个 Vue 组件,返回一个wrapper
第一个参数是组件,第二个是options对象,用于设置挂载选项,本例中通过propsData为Helloworld传值:msg
还有一个mount,它与shallowMount差别在于shallowMount在渲染组件时不渲染其子组件,避免了子组件可能带来的副作用(比如Http请求等)
ps:import { shallowMount }
类似ES6的新语法解构赋值,它用于部分引入,这里指定从'@vue/test-utils'
仅导入shallowMount
describe
用于创建一个测试集,第一个参数为本测试集描述字符串,第二个是一个函数
其中包含具体的测试代码(一些it/test块)
it
断言,与describe一样,第一个参数应该是测试描述,第二个是一个函数
其中通常是由expect组成的一个测试用例
ps: 还有一个test,在在Jest中它与it作用一致
wrapper
shallowMount或mount的返回值,它是一个包括了一个挂载组件或 vnode,以及测试该组件或 vnode 的方法
通过它可以使用该组件内定义的变量、方法、根DOM节点等等,同时提供了许多有用的方法供选择节点、触发事件或修改数据
expect
包裹一个变量,通常是由wrapper某个方法或其上选中的节点的方法或属性的返回值
在其上可以调用许多的toXX()方法来进行断言
expect(wrapper.text()).toMatch(msg)
本例中则是判断该组件内部的文本是否匹配msg字符串,其中msg也可以是一个正则表达式
如果不匹配则会抛出错误,该测试不通过
使用
jest默认会递归文件夹找到文件名以 .spec.js
或 .test.js
结尾的文件,把它们作为测试文件。
也可以在 jest.config.js
或package.json
(取决于初始化时的选择) 里设置
编写完测试后键入 npm run test:unit
运行测试,(该指令可以在package.json的scripts块中修改)
进阶
建议参阅官方文档https://vue-test-utils.vuejs.org/zh/api/
其中介绍、安装、教程三块为基础使用,可参考
API指'@vue/test-utils'
库中那些对象,如mount
关于wrapper及更多选项皆有涉及
同时建议使用vscode或其他能智能提示的编辑器,通过ctrl+左键点击相应函数或对象查看具体代码或更多同类函数,例如toBe、toEqual等等
踩过的坑
- 项目中使用了element-ui库的一些组件,一开始一直报错,说组件没注册,后来明白测试js独立于项目与 /src/main.js 一样需要使用
Vue.use()
注册用到的组件,全局指令Vue.directive等也都要重新定义 - 节点渲染时机很难把握,项目中需要先点一个按钮才会渲染第二个按钮,需要测试第二个按下后的变化,那么需要像下面这样:
wrapper.findAllComponents({ name: 'el-button' }).at(0).trigger('click')
it('描述', () => {
wrapper.findAllComponents({ name: 'el-button' }).at(2).trigger('click')
})
这两个点击不能放一起,不可以同在it外,也不可以在同一个it内,分开就可以...
3. 难以获取组件,去看官方文档会发现wrapper的find与findall都已经标上了Deprecation warning,即不推荐使用,并即将移除,要用findComponent与findAllComponents替代,
然而后面这两个不可以选取原生标签,而且好像也不支持选择器,最后无奈还是上了find,也可能是自己学得还不够
4. 与3同一个问题,多组件只能靠findAllComponents,并且通过.at()来选择其中某一个,然而若是之后代码里多加了个组件,那么整个顺序会乱,测试就得重写,很不舒服
结语
看到这里你已经是个成熟的测试了,可以尝试去大厂投简历,或者为开源社区做贡献,走上人生巅峰