Тестирование производительности компонентов

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

Монтирование компонентов

Для тестирования компонентов используется функция mount и shallowMount из Vue Test Utils.

  • mount полностью монтирует компонент, включая все дочерние компоненты.
  • shallowMount монтирует компонент, но заменяет дочерние компоненты на заглушки. Это полезно для изоляции теста, когда важна только логика родителя.

Пример монтирования:

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

const wrapper = mount(MyComponent, {
  props: { title: 'Тест' },
  global: {
    mocks: { $t: (msg) => msg } // мок для i18n
  }
})

Проверка рендеринга

После монтирования можно проверять, что компонент корректно отображает данные.

expect(wrapper.text()).toContain('Тест')
expect(wrapper.find('h1').exists()).toBe(true)

wrapper.find() и wrapper.findAll() позволяют искать элементы по селектору, компоненту или атрибуту. Это основной способ тестирования структуры DOM.

Работа с пропсами и реактивными данными

Изменение пропсов и состояния компонента можно тестировать динамически:

await wrapper.setProps({ title: 'Новый заголовок' })
expect(wrapper.text()).toContain('Новый заголовок')

Для реактивных данных используется wrapper.vm:

wrapper.vm.count = 10
await wrapper.vm.$nextTick()
expect(wrapper.find('.count').text()).toBe('10')

$nextTick() необходим для ожидания обновления DOM после изменения состояния.

Эмуляция событий

Vue Test Utils позволяет симулировать пользовательские действия:

await wrapper.find('button').trigger('click')
expect(wrapper.emitted()).toHaveProperty('increment')

Метод trigger может эмулировать любые события (click, input, submit). Метод emitted() возвращает объект с событиями, которые компонент испустил.

Тестирование асинхронной логики

Асинхронные операции требуют использования async/await или Jest-методов ожидания:

await wrapper.vm.fetchData()
await wrapper.vm.$nextTick()
expect(wrapper.find('.data').text()).toBe('Загружено')

Для компонентов с таймерами можно использовать Jest fake timers:

jest.useFakeTimers()
wrapper.vm.startTimer()
jest.advanceTimersByTime(5000)
await wrapper.vm.$nextTick()
expect(wrapper.find('.timer').text()).toBe('5')

Тестирование взаимодействия с дочерними компонентами

При использовании shallowMount дочерние компоненты заменяются заглушками. Проверка передачи пропсов выполняется через props():

const wrapper = shallowMount(ParentComponent)
const child = wrapper.findComponent(ChildComponent)
expect(child.props().value).toBe(42)

Можно проверять эмит событий дочерними компонентами:

child.vm.$emit('update', 'новое значение')
expect(wrapper.emitted('update')).toBeTruthy()

Работа с глобальными плагинами и провайдерами

Vue Test Utils поддерживает настройку глобальных плагинов, провайдеров и миксинов:

const wrapper = mount(MyComponent, {
  global: {
    plugins: [store],
    provide: { api: mockApi }
  }
})

Это позволяет тестировать компоненты в условиях, близких к реальному окружению приложения.

Проверка производительности

Тестирование производительности компонентов обычно сводится к измерению времени рендеринга и количества перерисовок.

  • Использование performance.now() вокруг монтирования:
const start = performance.now()
mount(MyComponent)
const duration = performance.now() - start
expect(duration).toBeLessThan(50) // миллисекунды
  • Проверка минимизации повторного рендеринга:
const spy = jest.spyOn(wrapper.vm, '$forceUpdate')
wrapper.vm.prop = 'новое значение'
await wrapper.vm.$nextTick()
expect(spy).toHaveBeenCalledTimes(1)
  • Замеры рендеринга с большим количеством данных позволяют выявлять узкие места в компоненте.

Практика модульного тестирования

  1. Изоляция: тестировать компоненты отдельно, используя shallowMount.
  2. Эмит событий: проверять корректность передачи событий вверх по иерархии.
  3. Пропсы и слоты: тестировать разные комбинации пропсов и содержимого слотов.
  4. Асинхронные операции: использовать async/await и мокирование внешних вызовов.
  5. Производительность: контролировать время рендеринга и количество перерисовок.

Vue Test Utils обеспечивает полный контроль над жизненным циклом компонента, позволяя создавать надежные, повторяемые и масштабируемые тесты.