这是我参与「第五届青训营 」伴学笔记创作活动的第 二 天 #青训营笔记
Vue3主要可以使用vue-test-utils和vitest组合做单测
依赖安装
npm install vitest@"0.25" happy-dom@"6.0.4" @vue/test-utils@"2.0.2"
//如果你用pnpm
pnpm i -D vitest@"0.25" happy-dom@"6.0.4" @vue/test-utils@"2.0.2"
修改vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
// ...
test: {
globals: true,
environment: 'happy-dom',
// 支持tsx组件
transformMode: {
web: [/.[tj]sx$/]
}
}
})
主要用法(示例代码在下面)
1.describe是起到一个分组的作用,其内第一个参数是接收一个字符串,可以自由的选择写什么,一般规范的话就是写上下面测试的内容是测试哪个组件的。例如‘Button.vue’。第二个参数接收一个函数,其内装着这个组件各个功能被测试的方式。
2.it和test意思是一样的,都是表示“测试”。其接收的第一个参数是接收一个字符串,是表示测试的具体内容,可以自由选择写什么。例如‘create’,'hadle click inside'。第二个参数接收一个函数,函数内需要一个定义一个测试用例,和一个测试表达式。
3.测试表达式就是expext(xxx).tobe(xxx)【tobe是匹配器,有非常多种,代表了匹配条件的不同】,字面意思,期望‘xxx’的值会是等于‘xxx’。
4.wrapper是固定写法,const wrapper = mount(() => Component) 根据需求可以变换成wrapper.classes(),mount(Component, {attachTo: document.getElementById('app')})等。
匹配器的文档jestjs.io/zh-Hans/doc…
wrapper的文档(例如wrapper.classes())test-utils.vuejs.org/api/#wrappe…
mount的文档(例如mount(Component, {attachTo: document.getElementById('app')})的attachTo)
test-utils.vuejs.org/api/#mount
describe('Button.vue', () => {
it('create', () => {
const wrapper = mount(() => <Button type="primary" />)
expect(wrapper.classes()).toContain('el-button--primary') })
test('handle click', async () => {
const wrapper = mount(() => (
<Button
v-slots={{
default: () => 'AXIOM',
}}
/>
))
await wrapper.trigger('click')
expect(wrapper.emitted()).toBeDefined()
})
}
案例分析(取自Element plus的button测试源码)
这部分主要是加深对测试的思想和结构的理解
Talk is cheap,show you the code
import { mount } from '@vue/test-utils'
import { markRaw } from 'vue'import { describe, expect, it } from 'vitest'
import { Search } from '@element-plus/icons-vue'import Button from '../src/button.vue'
//依赖部分此处略微删了几个,以免阅读起来不舒湖
//describe意思为描述,说明现在在测试的组件是Button.vuedescribe('Button.vue', () => {
//表明第一个测试的是他创建成功与否 it('create', () => {
//测试前先渲染一个组件primary样式的button组件(没用过Element plus的可以去官方文档看看使用说明)
//https://element-plus.gitee.io/zh-CN/component/button.html const wrapper = mount(() => <Button type="primary" />) //expect意思是期望,to contain的意思是包括。所以下面这句话意思就是希望wrapper(上面创建的).classes()包括(('el-button--primary')
//wrapper.classes()返回的是wrapper的class们
//所以这句话的意思是期望创建这个<Button type="primary" />组件后他的class里包含'el-button--primary'属性
expect(wrapper.classes()).toContain('el-button--primary') })
//表明第二个是测试他设定icon后icon是否在button上了 it('icon', () => {
//创建<Button icon={markRaw(Search)} />组件(markRaw可以把Search从响应式对象变为普通对象) const wrapper = mount(() => <Button icon={markRaw(Search)} />)
//在wrapper下寻找叫Search的组件,用exist()返回是否存在,toBeTruthy判断这个expect是非正确
//期望weapper能够找到一个叫Search的组件 expect(wrapper.findComponent(Search).exists()).toBeTruthy() })
}