Vue komponentlarini Vue Test Utils va Vitest bilan qanday test qilish mumkin?
Savol
Vue Test Utils va Vitest yordamida Vue komponentlarini test qilish qanday tashkil etiladi — mount qilish, hodisalarni simulyatsiya qilish, render'ni tekshirish, shallowMount va mount o'rtasidagi farq?
Qisqa javob
Vue Test Utils — testlarda Vue komponentlarini izolyatsiyalangan muhitda mount qilish uchun rasmiy kutubxona (odatda test runner sifatida Vitest bilan). Komponent mount() orqali (barcha bola komponentlarni render qilib) yoki shallowMount() orqali (bola komponentlar stab-o'rinbosarlar bilan almashtiriladi) mount qilinadi, shundan so'ng foydalanuvchi harakatlarini simulyatsiya qilish (trigger, setValue) va yakuniy DOM yoki emit qilingan hodisalarni tekshirish mumkin.
Batafsil javob
Mount qilish. mount(Component, options) (happy-dom/jsdom orqali) virtual DOM'da render qilingan komponentning haqiqiy nusxasi atrofida "o'rov" (VueWrapper) yaratadi. options orqali props, slots, global.plugins (test muhitida Pinia, router va h.k.ni ulash uchun) uzatiladi.
mount vs shallowMount.
mount— komponentni barcha bola komponentlari bilan birga haqiqatan render qiladi. Butun daraxt xatti-harakati muhim bo'lgan integratsion testlar uchun mos.shallowMount— faqat komponentning o'zini render qiladi, barcha bola komponentlarni esa stab-o'rinbosarlar bilan almashtiradi (bir xil nomga ega bo'sh teglar). Bu testni bola komponentlarning amalga oshirilish tafsilotlaridan izolyatsiya qiladi — faqat muayyan komponentning logikasi qiziqtirganda, uning bolalari emas (va bolalarning o'zi og'ir yoki alohida sozlashni talab qilganda) unit-testlar uchun foydali.
Hodisalarni simulyatsiya qilish. wrapper.find('button').trigger('click') DOM hodisasini emulyatsiya qiladi; kiritish maydonlari uchun — input/changeni ham ishga tushirib, v-modelni yangilaydigan wrapper.find('input').setValue('matn'). Ikkala metod ham asinxron va Vue DOM yangilanish siklini o'tkazishga ulgurishi uchun (kapot ostida await nextTick()) awaited qilinishi kerak.
Natijani tekshirish.
wrapper.text()/wrapper.html()— render qilingan tarkibni tekshirish.wrapper.find(selector).exists()— elementning mavjudligini tekshirish.wrapper.emitted('event-name')— komponent qaysi hodisalarni va qanday argumentlar bilan emit qilganini tekshirish (haqiqiy ota komponentga bog'liq bo'lmagan bola komponentlar unit-testi uchun).wrapper.props()/wrapper.setProps({...})— test doirasida komponent props'larini o'qish va o'zgartirish.
Odatda amalga oshirish tafsilotlari emas, xatti-harakat test qilinadi: X metodi chaqirilganmi emas, bosishdan keyin ekranda Y matni paydo bo'ldimi yoki mana shunday payload bilan hodisa emit qilindimi — bu testlarni komponentning ichki tuzilishini refaktoring qilishga chidamli qiladi.
Misol
<!-- Counter.vue -->
<script setup>
import { ref } from 'vue'
const props = defineProps({ initial: { type: Number, default: 0 } })
const emit = defineEmits(['limit-reached'])
const count = ref(props.initial)
function increment() {
count.value++
if (count.value >= 5) emit('limit-reached')
}
</script>
<template>
<button @click="increment">Hisoblagich: {{ count }}</button>
</template>
// Counter.spec.js
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import Counter from './Counter.vue'
describe('Counter', () => {
it('bosishda qiymatni oshiradi', async () => {
const wrapper = mount(Counter, { props: { initial: 0 } })
expect(wrapper.text()).toContain('Hisoblagich: 0')
await wrapper.find('button').trigger('click')
expect(wrapper.text()).toContain('Hisoblagich: 1')
})
it('5ga yetganda limit-reached emit qiladi', async () => {
const wrapper = mount(Counter, { props: { initial: 4 } })
await wrapper.find('button').trigger('click')
expect(wrapper.emitted('limit-reached')).toHaveLength(1)
})
})
Qo'shimcha savollar
mounto'rnigashallowMountni qachon tanlash kerak va komponentlar daraxtini to'liqmountqilishning qanday xavflari bor?- Pinia store yoki Vue Router ishlatadigan komponentni qanday test qilish mumkin?
wrapper.emitted()komponentning ichki holatini to'g'ridan-to'g'ri tekshirishdan nimasi bilan foydaliroq?