Перейти к основному содержимому

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 для получения информации.

Мокирование встроенных composables

В случае, если ваш компонент использует нативную функцию Nuxt composable, например useNuxtData, WebdriverIO автоматически создаст мок для этих функций и позволит вам изменять их поведение или выполнять проверки, например:

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

// например, ваш компонент использует вызов `useNuxtData` следующим образом
// `const { data: posts } = useNuxtData('posts')`
// в вашем тесте вы можете проверить это
expect(useNuxtData).toBeCalledWith('posts')
// и изменить их поведение
mocked(useNuxtData).mockReturnValue({
data: [...]
})

Обработка сторонних composables

Все сторонние модули, которые могут улучшить ваш проект Nuxt, не могут быть автоматически замокированы. В таких случаях вам нужно вручную создать моки, например, если ваше приложение использует модуль плагина Supabase:

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

и вы создаете экземпляр Supabase где-то в ваших composables, например:

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