前言:网上一大堆的单元测试,但是很少针对vue的单元测试,不过也有一些视频简单的讲解了,这里为了方便各位前端朋友快速上手,简单过一遍 单元测试
这里不举例我自己的页面,怕大家看不懂,以下代码片段,有部分会来自网上
1. 创建页面
在根目录下找到 tests文件夹在iview文件下创建以实际测试文件路径相仿的文件
比如我在 src/iview/Home 下 有一个 Home.vue
那么我们的 单元测试文件就要
tests/iview/Home/Home.spec.js
如果外面那个 Home.vue 要测,那你 一样的文件位置要对应
注意:测试文件要以 被测文件名.spec.js 命名
2. 引入各种文件
引入 @vue/test-utils (这里默认你已经安装好引入 @vue/test-utils 并且配置好)
import { mount, flushPromises } from '@vue/test-utils'
引入组件(必要)
无论是 子组件,自定义组件,框架内的组件,自身文件,都要一一引入
import Home from '@/views/Home/Home.vue' // 自身
import HomeTable from '@/components/HomeTable.vue' // 子组件
以element为例引入组件
import { ElMessageBox, ElTableColumn, ElTable } from 'element-plus'
引入接口(有需要才引入,这里只是扩展)
import { tableList } from '@/api/index'
引入插件 (有需要才引入,这里只是扩展)
以 lodash-es.js 举例
lodash-es.js 是一个处理 各种形式类型数据的一个插件,比如我们深拷贝一个对象,传统 js 处理就是 JSON.parse(JSON.stringify(…)) 在我们项目中是不推荐的,所以利用 lodash-es.js 处理,详情可以看我之前的文章
import { cloneDeep } from 'lodash-es'
引入路由 (有需要才引入,这里只是扩展)
import { useRouter } from 'vue-router'
引入Vuex (有需要才引入,这里只是扩展)
import { createStore } from 'vuex'
3. 调用各种引入的文件
把组件相关全部调用
const componentGlobal = {
components: {
'home-table': HomeTable, // 组件
ElMessageBox, // element的组件(框架组件)
ElTableColumn,
ElTable
}
}
编写接口返回(假)数据
const mockListData = {
"phone": "1354490525",
"isVip": 0,
"createTime": "2021-12-06 00:00:00",
"name": "测试人员1",
"id": "h5214so514w1206",
...
}
const mockResponse = {
data: {
"msg": "success",
"code": 200,
"page": {
"totalCount": 1,
"pageSize": 10,
"totalPage": 1,
"currPage": 1,
"list": [
mockListData
]
}
}
}
mock 接口
将上面的数据当作返回数据
jest.mock('@/api/index', () => ({
tableList: jest.fn(() => Promise.resolve(mockResponse)),
}))
mock 对话框/路由 (部分组件时找不到节点的,需要mock)
// mock 路由
jest.mock('vue-router', () => ({
useRouter: jest.fn(() => ({
push: () => ({})
}))
}))
// mock 对话框 (他是通过 ElMessageBox. 弄出来,并没有把节点写在页面上,所以需要mock)
jest.mock('element-plus', () => ({
...jest.requireActual('element-plus'),
ElMessageBox: {
confirm: jest.fn(),
cancel: jest.fn(),
}
}))
有用到 Vuex 需定义 store
const store = createStore({
modules: {
user: {
namespaced: true,
state: {
userId: "07cbccc0039"
},
},
}
})
4. 开始测试
挂载
describe('测试 Home 页面是否正常工作', () => { // 中文部分按自己的来,在只用来展示
const mockScrollTo = jest.fn()
let wrapper: VueWrapper<ComponentPublicInstance<any>>
beforeEach(() => {
wrapper = mount(Home, {
global: {
...componentGlobal,
provide: {
scrollTo : mockScrollTo,
store /// 用到 Vuex 的可以加上
},
}
})
})
})
如果时测组件,还要把props的值加上
describe('测试 HomeTable 组件是否正常工作', () => {
let wrapper: VueWrapper<ComponentPublicInstance<any>>
beforeEach(() => {
wrapper = mount(HomeTable, {
props: {
dataList: cloneDeep(mockListData), // cloneDeep是深拷贝
},
global: {
components,
},
})
})
})
在这包裹下我们可以把我们要测试的东西全部通过
it('测试内容', ()=>{})
测试展示
利用
wrapper.findAll()
wrapper.find()
wrapper.findComponent()
wrapper.findAllComponents()
这些 api 来校验页面是否预期展示需要的组件
测试点击
一样先找到要点击按钮的节点,通过 trigger(‘click’) 模拟点击
it('测试点击', async () => {
wrapper.find('.add').trigger('click') // 找到节点,模拟点击
})
如果节点较多,则需要找其中一个进行测试
it('测试点击', async () => {
const ElTableColumnComponent = wrapper.find('.tableList') // 找到节点
ElTableColumnComponent.findAll('.updateBtn')[0].trigger('click') // 模拟点击
})
测试接口
如果点击后他要执行某些操作,如跑接口
it('测试接口', async () => {
ElTableColumnComponent.findAll('.deleteBtn')[0].trigger('click')
// deleteUser 指接口名
// mockImplementationOnce 官方api 指调用一次
// delMockResponse 返回数据
const delMockResponse = {
"msg": "success",
"code": 200
}; // 注意这个;
(deleteUser as jest.Mock<any>).mockImplementationOnce(() => Promise.resolve(delMockResponse)) // 模拟接口
})
一般测试只测他流程能不能走通
测试组件返回信息
我们有时候会用到子组件,子组件会 emit 回一个方法和参数
例如
<home-table
:data-list="tableList"
@changeDate="changeDateHandle"
/>
it('测试子组件返回', async () => {
const data = {
"id": "cs24545132hs5"
}
const HomeTableComponent = wrapper.findComponent(HomeTable) // 找到这个组件节点
HomeTableComponent.vm.$emit('changeDate', data) // newMockListData 返回数据
})
测试跳转
it('测试页面跳转是否正常', async () => {
const push = jest.fn()
useRouter.mockImplementationOnce(() => ({ push }))
// mock 完毕需要重新挂载
const wrapper = mount(MyPatientList, {
global: {
...componentGlobal,
provide: {
scrollTo: mockScrollTo
}
}
})
})
watch 测试
watch是监听,所以我们直接给监听的值赋一个新的值就可以了
wrapper.vm.要赋值的对象 = 新的值
5. 进阶
测试页面写完 请运行命令
npm run ut:coverage
可以在项目内 coverage\lcov-report 找到一个 index.html 页面,点击既可以查看该项目测试覆盖率
一般 绿色就代表单元测试通过,当然覆盖率越高越好
文件内红色的代码没测到
多看文档 文档虽然不是很清晰,但是基本上的方法还是够用的
官方文档
多写多练
6. 常用命令
请浏览我这篇文章