跟着步骤,一步一步的上手Vue单元测试,基本上覆盖了常用的场景,复杂的场景,参考官方文档吧。
- 创建vue app
npm install -g vue-vli
vue init webpack vue-jest
安装过程单元测试方案选择jest
安装完成后jest的配置文件在src/test/unit/jest.conf.js中
{
rootDir: path.resolve(__dirname, '../../'),
moduleFileExtensions: [
'js',
'json',
'vue'
],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
transform: {
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'
},
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
setupFiles: ['<rootDir>/test/unit/setup'],
coverageDirectory: '<rootDir>/test/unit/coverage',
collectCoverageFrom: [
'src/**/*.{js,vue}',
'!src/main.js',
'!src/router/index.js',
'!**/node_modules/**'
],
testURL: 'http://localhost/'
}
2. 运行默认测试用例
npm run test
可能会出现报错
解决方案
在jest.conf.js中设置testURL
module.exports = {
...
testURL: 'http://localhost/'
}
再次测试
3. 组件测试
增加HelloWorld.spec.js文件
import Vue from 'vue'
import HelloWorld from '@/components/HelloWorld'
describe('HelloWorld.vue', () => {
it('should render right contents', () => {
// create a copy of the original component
const Constructor = vue.extend(HelloWorld)
// instances and mounts the component
const vm = new Constructor().$mount()
expect(vm.msg).toEqual('Welcome to Your Vue.js App')
})
})
运行 npm run test 执行测试
4. 浅渲染测试
浅渲染测试是指渲染一个组件自身而不渲染其子组件,这样既符合单元测试的意义,又避免子组件的一些副作用(HTTP请求,获取store数据)
Vue要实现浅渲染,需要确保安装以下依赖jest、babal-jest、vue-test-utils,如果没有安装则增加相关依赖
yarn add -D @vue/test-utils jest babel-jest
增加App.spec.js文件
import { shallowMount } from '@/vue/test-utils'
import App from '../../../src/App'
decsribe('App.spec.js', () => {
let wrapper
beforeEach(() => {
wrapper = shallowMount(App /*{}*/)
})
it('should has html structure', () => {
expect(wrapper.element).toMatchSnapshot()
})
})
运行 npm run test 执行测试,测试的快照文件中并没有渲染_App_的子组件
5. 断言emited 事件
每个mount的wrapper都记录emited的事件,可以通过wrapper.emited()获取事件
it('get emited event', () => {
const wrapper = mount(Conponent)
wrapper.vm.$emit('foo', 123)
expect(wrapper.emited().foo.length).toBe(1)
expect(wrapper.emited().foo[0]).toEqual([123])
})
6. 修改组件的state
wrapper.setData({count: 10})
wrapper.setProps({name: 'jay'})
7. 使用全局的plugins和mixins
import { createLocalVue, mount } from '@/vue/test-utils'
// create a copy of Vue
const localVue = createLocalVue()
// install plugins as normal
localVue.use(MyPlugin)
// pass the localVue to the mount options
mount(Component, {
localVue
})
8. mock 注入
对于全局的注入(store、route)可以使用mock
const $route = {path: 'http://www.example-path.com'}
const wrapper = shallowMount(Component, {
mocks: {
$route
}
})
expect(wrapper.vm.$route.path).toBe($route.path)
9. 编写测试用例的原则
对于UI 组件的测试不要求覆盖到每一行,一方面这样需要考虑的情况比较多,另一方面也会大大增加测试的时间。应该多关注公共的接口方法,只关心输入和输出。
10. 参考链接