[vue3的单测 | 青训营笔记]

77 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 二 天 #青训营笔记

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')  })
  //表明第二个是测试他设定iconicon是否在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()  })
}