Перейти до основного вмісту

Vue.js

Vue.js - це зручний, продуктивний та універсальний фреймворк для створення веб-інтерфейсів. Ви можете тестувати компоненти Vue.js безпосередньо в реальному браузері за допомогою WebdriverIO та його браузерного запускача.

Налаштування

Щоб налаштувати WebdriverIO у вашому проекті Vue.js, дотримуйтеся інструкцій у нашій документації з тестування компонентів. Переконайтеся, що обрали vue як пресет у параметрах вашого запускача, наприклад:

// wdio.conf.js
export const config = {
// ...
runner: ['browser', {
preset: 'vue'
}],
// ...
}
інформація

Якщо ви вже використовуєте Vite як сервер розробки, ви також можете повторно використовувати вашу конфігурацію з vite.config.ts у вашій конфігурації WebdriverIO. Для отримання додаткової інформації див. viteConfig у опціях запускача.

Пресет Vue вимагає встановлення @vitejs/plugin-vue. Також ми рекомендуємо використовувати Testing Library для рендерингу компонента на тестовій сторінці. Для цього вам потрібно встановити наступні додаткові залежності:

npm install --save-dev @testing-library/vue @vitejs/plugin-vue

Потім ви можете запустити тести за допомогою:

npx wdio run ./wdio.conf.js

Написання тестів

Припустимо, у вас є наступний компонент Vue.js:

./components/Component.vue
<template>
<div>
<p>Times clicked: {{ count }}</p>
<button @click="increment">increment</button>
</div>
</template>

<script>
export default {
data: () => ({
count: 0,
}),

methods: {
increment() {
this.count++
},
},
}
</script>

У вашому тесті відрендеріть компонент у DOM і запустіть перевірки на ньому. Ми рекомендуємо використовувати або @vue/test-utils, або @testing-library/vue для підключення компонента до тестової сторінки. Для взаємодії з компонентом використовуйте команди WebdriverIO, оскільки вони поводяться більш наближено до реальних взаємодій користувача, наприклад:

vue.test.js
import { $, expect } from '@wdio/globals'
import { mount } from '@vue/test-utils'
import Component from './components/Component.vue'

describe('Vue Component Testing', () => {
it('increments value on click', async () => {
// The render method returns a collection of utilities to query your component.
const wrapper = mount(Component, { attachTo: document.body })
expect(wrapper.text()).toContain('Times clicked: 0')

const button = await $('aria/increment')

// Dispatch a native click event to our button element.
await button.click()
await button.click()

expect(wrapper.text()).toContain('Times clicked: 2')
await expect($('p=Times clicked: 2')).toExist() // same assertion with WebdriverIO
})
})

Ви можете знайти повний приклад набору тестів компонентів WebdriverIO для Vue.js у нашому репозиторії прикладів.

Тестування Асинхронних Компонентів у Vue3

Якщо ви використовуєте Vue v3 і тестуєте асинхронні компоненти, такі як:

<script setup>
const res = await fetch(...)
const posts = await res.json()
</script>

<template>
{{ posts }}
</template>

Ми рекомендуємо використовувати @vue/test-utils і невеликий обгортку suspense для відтворення компонента. На жаль, @testing-library/vue ще не підтримує це. Створіть файл helper.ts з наступним вмістом:

import { mount, type VueWrapper as VueWrapperImport } from '@vue/test-utils'
import { Suspense } from 'vue'

export type VueWrapper = VueWrapperImport<any>
const scheduler = typeof setImmediate === 'function' ? setImmediate : setTimeout

export function flushPromises(): Promise<void> {
return new Promise((resolve) => {
scheduler(resolve, 0)
})
}

export function wrapInSuspense(
component: ReturnType<typeof defineComponent>,
{ props }: { props: object },
): ReturnType<typeof defineComponent> {
return defineComponent({
render() {
return h(
'div',
{ id: 'root' },
h(Suspense, null, {
default() {
return h(component, props)
},
fallback: h('div', 'fallback'),
}),
)
},
})
}

export function renderAsyncComponent(vueComponent: ReturnType<typeof defineComponent>, props: object): VueWrapper{
const component = wrapInSuspense(vueComponent, { props })
return mount(component, { attachTo: document.body })
}

Потім імпортуйте і тестуйте компонент так:

import { $, expect } from '@wdio/globals'

import { renderAsyncComponent, flushPromises, type VueWrapper } from './helpers.js'
import AsyncComponent from '/components/SomeAsyncComponent.vue'

describe('Testing Async Components', () => {
let wrapper: VueWrapper

it('should display component correctly', async () => {
const props = {}
wrapper = renderAsyncComponent(AsyncComponent, { props })
await flushPromises()
await expect($('...')).toBePresent()
})

afterEach(() => {
wrapper.unmount()
})
})

Тестування компонентів Vue у Nuxt

Якщо ви використовуєте веб-фреймворк Nuxt, WebdriverIO автоматично включить функцію auto-import і зробить тестування ваших компонентів Vue і сторінок Nuxt простим. Однак будь-які модулі Nuxt, які ви можете визначити у своїй конфігурації та які потребують контексту додатка Nuxt, не можуть підтримуватися.

Причини для цього:

  • WebdriverIO не може ініціювати додаток Nuxt виключно в середовищі браузера
  • Наявність тестів компонентів, які занадто сильно залежать від середовища Nuxt, створює складність, і ми рекомендуємо запускати ці тести як e2e-тести
інформація

WebdriverIO також надає службу для запуску e2e-тестів у додатках Nuxt, див. webdriverio-community/wdio-nuxt-service для отримання інформації.

Мокінг вбудованих композаблів

Якщо ваш компонент використовує нативний композабл Nuxt, наприклад useNuxtData, WebdriverIO автоматично мокує ці функції та дозволяє вам змінювати їхню поведінку або виконувати перевірки проти них, наприклад:

import { mocked } from '@wdio/browser-runner'

// e.g. your component uses calls `useNuxtData` the following way
// `const { data: posts } = useNuxtData('posts')`
// in your test you can assert against it
expect(useNuxtData).toBeCalledWith('posts')
// and change their behavior
mocked(useNuxtData).mockReturnValue({
data: [...]
})

Обробка композаблів сторонніх розробників

Усі модулі сторонніх розробників, які можуть покращити ваш проект Nuxt, не можуть автоматично бути мокованими. У таких випадках вам потрібно мокувати їх вручну, наприклад, якщо ваш додаток використовує плагін модуля Supabase:

export default defineNuxtConfig({
modules: [
"@nuxtjs/supabase",
// ...
],
// ...
});

і ви створюєте екземпляр Supabase десь у своїх композаблах, наприклад:

const superbase = useSupabaseClient()

тест не вдасться через:

ReferenceError: useSupabaseClient is not defined

Тут ми рекомендуємо або мокувати весь модуль, який використовує функцію useSupabaseClient, або створити глобальну змінну, яка мокує цю функцію, наприклад:

import { fn } from '@wdio/browser-runner'
globalThis.useSupabaseClient = fn().mockReturnValue({})

Welcome! How can I help?

WebdriverIO AI Copilot