what is vitest & test-utils
vitest 是由 vite 提供支持的極速單元測(cè)試框架,VueTestUtils 是 Vue.js 的官方測(cè)試實(shí)用程序庫(kù),vitest 本身是不支持單元組件測(cè)試的,需要配合 test-utils 來(lái)完成組件單元測(cè)試,安裝與基本 API 就不再贅述,學(xué)會(huì)閱讀文檔與查找資料是一個(gè)程序員的基本功
demo
/* Component */
<template>
<div>
<div class="test-utils-value">值為:{{ num }}</div>
<button class="test-utils-button" @click="increment">測(cè)試按鈕</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('組件單元測(cè)試', () => {
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 由一個(gè)組件和測(cè)試文件組成
- 組件的邏輯非常簡(jiǎn)單,按下按鈕則數(shù)字+1,頁(yè)面顯示實(shí)時(shí)數(shù)字
- 測(cè)試代碼中使用 test-utils 庫(kù)的 shallowMount 方法淺渲染掛載組件(*:淺渲染只渲染當(dāng)前組件,不會(huì)渲染它的子組件,從而避免在測(cè)試中與子組件的行為產(chǎn)生干擾)
- 組件通過(guò) find 方法返回查找元素,再通過(guò) text 方法返回元素的文本內(nèi)容
- 然后使用 vitest 庫(kù)的 expect 創(chuàng)建斷言,toContain 是斷言檢查值是否在數(shù)組中,toBe 是斷言基礎(chǔ)對(duì)象是否相等
- trigger 是 test-utils 中觸發(fā) DOM 事件的方法,demo 中觸發(fā)了點(diǎn)擊事件,模擬用戶按下了按鈕的操作,按下按鈕前后都斷言了,會(huì)判斷實(shí)際執(zhí)行結(jié)果與預(yù)期結(jié)果是否一致,如果不一致則會(huì)拋出錯(cuò)誤
- 如將
tobe('值為:2')
改為tobe('值為:3')
,就會(huì)提示哪一個(gè)測(cè)試文件中的哪一個(gè)測(cè)試用例失敗,并展示錯(cuò)誤的預(yù)期值和實(shí)際的執(zhí)行結(jié)果
- Expected "值為:3"
+ Received "值為:2"
tips
雖然這是一個(gè)非常簡(jiǎn)單 demo,但它還是有很多值得注意的知識(shí)點(diǎn)的文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-840457.html
- describe 可以在文件頂層直接使用
test
和bench
,它們會(huì)被收集為隱式套件的一部分,也可以用describe
在當(dāng)前上下文定義一個(gè)新套件,作為一組相關(guān)的測(cè)試或嵌套套件 - it
it
是test
的別名,使用it
或test
都是可以的 - shallowMount 按照文檔描述它是使用掛載組件的別名,所以也可以使用
mount(Component, { shallow: true })
來(lái)淺渲染掛載組件,shallow 的默認(rèn)值是 false
- async/await 可以看到 trigger 前使用了 await,這與我們尋常使用 async/await 有一點(diǎn)細(xì)微的差別,假如我們?nèi)サ?async/await,測(cè)試用例將會(huì)失敗,因?yàn)榘粹o雖然按下了,值也自增了,但 vue 不會(huì)立即更新 DOM,而是等到下一個(gè)事件循環(huán)勾選之后再更新,所以斷言會(huì)在在 vue 更新之前被調(diào)用,拿到的實(shí)際執(zhí)行結(jié)果還是初始值 1,與預(yù)期值 2 不符,然后拋出錯(cuò)誤,這感覺(jué)是不是很熟悉,這不就像 Vue 的異步更新策略導(dǎo)致我們對(duì)數(shù)據(jù)的修改不會(huì)立馬體現(xiàn)到頁(yè)面變化上,此時(shí)如果想要立即獲取更新后的 dom 的狀態(tài),我們就需要使用到…對(duì),沒(méi)錯(cuò)就是我們的老朋友
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')
})
因?yàn)檫@是很常見(jiàn)的一個(gè)問(wèn)題,test-utils提供了一個(gè)快捷方式,可以直接在await后跟觸發(fā)DOM的事件,省略掉
nexttick()
,即await wrapper.find(btn).trigger('click')
,如此一來(lái)我們斷言的實(shí)際結(jié)果就是自增過(guò)后的數(shù)字,與預(yù)期結(jié)果相符,測(cè)試用例通過(guò)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-840457.html
到了這里,關(guān)于vitest單元測(cè)試配合@vue/test-utils之組件單元測(cè)試篇的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!