Сеп up тестового окружения

Vue Test Utils — официальный низкоуровневый инструмент для тестирования компонентов Vue. Он не является тестовым раннером и не выполняет тесты самостоятельно. Его задача — предоставить API для монтирования компонентов, управления их состоянием и взаимодействия с DOM в тестовой среде.

Типичная связка выглядит так:

  • Vue Test Utils — работа с компонентами
  • Vitest или Jest — запуск тестов, ассерты, моки
  • jsdom — эмуляция браузерного окружения

Корректная настройка окружения критична: ошибки на этом этапе приводят к нестабильным тестам, сложным мокам и ложным падениям.


Выбор тестового раннера

Vitest как стандарт для Vue 3

Для Vue 3 де-факто стандартом стал Vitest:

  • Нативная поддержка Vite
  • Быстрый запуск
  • Полная совместимость с Jest API
  • Простая интеграция с Vue Test Utils

Установка:

npm install -D vitest @vue/test-utils jsdom

Для проектов на Vue 2 чаще используется Jest, но архитектура настройки схожа.


Базовая структура тестового окружения

Минимальная структура проекта с тестами:

src/
  components/
    MyComponent.vue
tests/
  MyComponent.spec.js
vitest.config.js

Разделение src и tests упрощает навигацию и исключает попадание тестов в сборку.


Конфигурация Vitest для Vue Test Utils

Подключение jsdom

Vue Test Utils требует DOM-окружение. В vitest.config.js:

import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  test: {
    environment: 'jsdom'
  }
})

Без jsdom любые операции с DOM (mount, find, trigger) будут недоступны.


Установка и инициализация Vue Test Utils

Vue Test Utils не требует глобальной инициализации, но предоставляет объект глобальных настроек.

Импорт:

import { mount, shallowMount } from '@vue/test-utils'

Ключевые функции:

  • mount — полное монтирование компонента с дочерними компонентами
  • shallowMount — дочерние компоненты заменяются заглушками

Глобальные настройки тестов

Файл глобальной инициализации

Часто требуется единая конфигурация для всех тестов: плагины, глобальные компоненты, директивы. Для этого используется setup-файл.

В vitest.config.js:

test: {
  setupFiles: './tests/setup.js'
}

Содержимое tests/setup.js:

import { config } from '@vue/test-utils'

Глобальные компоненты

Регистрация глобальных компонентов:

config.global.components = {
  BaseButton: {
    template: '<button><slot /></button>'
  }
}

Это избавляет от необходимости регистрировать их в каждом тесте.


Глобальные плагины

Подключение Vue-плагинов:

import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  locale: 'ru',
  messages: {}
})

config.global.plugins = [i18n]

Важно: плагины создаются один раз и переиспользуются, если они не зависят от состояния теста.


Глобальные моки

Моки глобальных свойств

Для this.$router, this.$route, this.$t и аналогов:

config.global.mocks = {
  $t: (key) => key,
  $router: {
    push: vi.fn()
  }
}

Это позволяет изолировать компонент от реальной реализации.


Работа с provide / inject

Vue Test Utils позволяет передавать provide напрямую:

mount(MyComponent, {
  global: {
    provide: {
      apiService: mockApi
    }
  }
})

Для часто используемых зависимостей допустимо вынести их в глобальную конфигурацию, но это снижает прозрачность тестов.


Настройка stubs

Глобальные заглушки компонентов

config.global.stubs = {
  RouterLink: true,
  RouterView: true
}

Или кастомная реализация:

RouterLink: {
  template: '<a><slot /></a>'
}

Заглушки ускоряют тесты и уменьшают количество неявных зависимостей.


Изоляция тестов и сброс состояния

Vue Test Utils не очищает глобальные настройки автоматически. Если используются моки с состоянием:

afterEach(() => {
  vi.clearAllMocks()
})

При изменении config.global в конкретных тестах необходимо явно возвращать состояние.


Настройка CSS и сторонних ресурсов

Отключение стилей

CSS не влияет на логику компонентов, но может ломать тесты при импорте:

test: {
  css: false
}

Моки ассетов

Если компоненты импортируют изображения или SVG, Vitest автоматически их мокает, но при кастомных загрузчиках может потребоваться ручная настройка.


Работа с Composition API и async setup

Vue Test Utils корректно обрабатывает setup, но асинхронные операции требуют ожидания:

import { flushPromises } from '@vue/test-utils'

await flushPromises()

flushPromises должен быть доступен глобально или импортироваться явно.


Проверка корректности окружения

Простейший smoke-тест:

import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'

test('component mounts', () => {
  const wrapper = mount(MyComponent)
  expect(wrapper.exists()).toBe(true)
})

Если тест проходит, окружение настроено корректно.


Принципы качественного setup

Минимальность В глобальной конфигурации размещаются только действительно общие зависимости.

Предсказуемость Каждый тест должен явно понимать, какие плагины и моки участвуют.

Изоляция Глобальные моки не должны хранить состояние между тестами.

Повторяемость Окружение должно одинаково работать локально и в CI.


Частые ошибки настройки

  • Использование mount без jsdom
  • Глобальные моки с состоянием
  • Смешивание реальных и заглушенных плагинов
  • Импорт Vue Test Utils разных версий
  • Настройка логики тестов в setupFiles

Итоговая роль setup-слоя

Setup тестового окружения — фундамент всей системы тестирования. Правильно настроенный Vue Test Utils позволяет писать короткие, стабильные и изолированные тесты, не тратя время на инфраструктурные проблемы и отладку среды.