vitest单元测试配合@vue/test-utils之组件单元测试篇
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
what is vitest & test-utils
vitest 是由 vite 提供支持的极速单元测试框架,VueTestUtils 是 Vue.js 的官方测试实用程序库,vitest 本身是不支持单元组件测试的,需要配合 test-utils 来完成组件单元测试,安装与基本 API 就不再赘述,学会阅读文档与查找资料是一个程序员的基本功
demo
/* Component */
<template>
<div>
<div class="test-utils-value">值为:{{ num }}</div>
<button class="test-utils-button" @click="increment">测试按钮</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { Ref } from 'vue'
const num: Ref<number> = ref(1)
function increment() {
num.value++
}
</script>
// spec | test
import { describe, it, expect } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import AddNum from '@/views/AddNum.vue'
describe('组件单元测试', () => {
it('test1', async () => {
const wrapper = shallowMount(AddNum)
const btn = '.test-utils-button'
const value = '.test-utils-value'
expect(wrapper.find(value).text()).toContain('值为:1')
await wrapper.find(btn).trigger('click')
expect(wrapper.find(value).text()).toBe('值为:2')
})
})
- demo 由一个组件和测试文件组成
- 组件的逻辑非常简单,按下按钮则数字+1,页面显示实时数字
- 测试代码中使用 test-utils 库的 shallowMount 方法浅渲染挂载组件(*:浅渲染只渲染当前组件,不会渲染它的子组件,从而避免在测试中与子组件的行为产生干扰)
- 组件通过 find 方法返回查找元素,再通过 text 方法返回元素的文本内容
- 然后使用 vitest 库的 expect 创建断言,toContain 是断言检查值是否在数组中,toBe 是断言基础对象是否相等
- trigger 是 test-utils 中触发 DOM 事件的方法,demo 中触发了点击事件,模拟用户按下了按钮的操作,按下按钮前后都断言了,会判断实际执行结果与预期结果是否一致,如果不一致则会抛出错误
- 如将
tobe('值为:2')
改为tobe('值为:3')
,就会提示哪一个测试文件中的哪一个测试用例失败,并展示错误的预期值和实际的执行结果
- Expected "值为:3"
+ Received "值为:2"
tips
虽然这是一个非常简单 demo,但它还是有很多值得注意的知识点的
- describe 可以在文件顶层直接使用
test
和bench
,它们会被收集为隐式套件的一部分,也可以用describe
在当前上下文定义一个新套件,作为一组相关的测试或嵌套套件 - it
it
是test
的别名,使用it
或test
都是可以的 - shallowMount 按照文档描述它是使用挂载组件的别名,所以也可以使用
mount(Component, { shallow: true })
来浅渲染挂载组件,shallow 的默认值是 false
- async/await 可以看到 trigger 前使用了 await,这与我们寻常使用 async/await 有一点细微的差别,假如我们去掉 async/await,测试用例将会失败,因为按钮虽然按下了,值也自增了,但 vue 不会立即更新 DOM,而是等到下一个事件循环勾选之后再更新,所以断言会在在 vue 更新之前被调用,拿到的实际执行结果还是初始值 1,与预期值 2 不符,然后抛出错误,这感觉是不是很熟悉,这不就像 Vue 的异步更新策略导致我们对数据的修改不会立马体现到页面变化上,此时如果想要立即获取更新后的 dom 的状态,我们就需要使用到…对,没错就是我们的老朋友
nexttick()
import { nextTick } from 'vue'
it('test1', async () => {
const wrapper = shallowMount(AddNum)
const btn = '.test-utils-button'
const value = '.test-utils-value'
expect(wrapper.find(value).text()).toContain('值为:1')
wrapper.find(btn).trigger('click')
await nexttick()
expect(wrapper.find(value).text()).toBe('值为:2')
})
因为这是很常见的一个问题,test-utils提供了一个快捷方式,可以直接在await后跟触发DOM的事件,省略掉
nexttick()
,即await wrapper.find(btn).trigger('click')
,如此一来我们断言的实际结果就是自增过后的数字,与预期结果相符,测试用例通过
GitHub 加速计划 / vu / vue
80
16
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:4 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 6 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 6 个月前
更多推荐
已为社区贡献1条内容
所有评论(0)