Snapshot-тесты фиксируют текущее состояние компонента и позволяют отслеживать любые изменения его рендера во времени. В контексте Vue Test Utils под состоянием обычно понимается HTML-разметка, возвращаемая компонентом после монтирования, а также иногда сериализованная структура Virtual DOM. Основная идея заключается в сравнении сохранённого эталонного снимка с актуальным результатом рендера при каждом запуске тестов.
Snapshot-подход не проверяет бизнес-логику напрямую, а контролирует визуальную и структурную целостность компонента. Это особенно важно для компонентов с большим количеством условий отображения, слотов и вложенных компонентов.
При первом запуске теста создаётся снимок — текстовый файл, обычно
сохраняемый рядом с тестом или в специальной директории
__snapshots__. Этот файл содержит сериализованное
представление результата вызова wrapper.html() или
wrapper.element.
При последующих запусках:
Сравнение строгое: любое изменение тегов, атрибутов, порядка элементов или текста приводит к несовпадению.
import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
test('snapshot рендера компонента', () => {
const wrapper = mount(MyComponent)
expect(wrapper.html()).toMatchSnapshot()
})
При первом запуске будет создан файл:
exports[`snapshot рендера компонента 1`] = `
<div class="my-component">
<span>Текст</span>
</div>
`
Vue Test Utils здесь отвечает за корректное монтирование компонента, а Jest — за хранение и сравнение снимков.
Ключевой момент snapshot-тестирования — осознанный выбор того, что именно сохраняется:
wrapper.html()
wrapper.element
wrapper.vm.$data
Выбор зависит от цели теста. Для контроля шаблона используется HTML, для логики — данные или computed-свойства.
Компоненты во Vue часто изменяют рендер в зависимости от входных свойств. Snapshot-тесты позволяют зафиксировать каждую значимую конфигурацию.
test('snapshot с активным состоянием', () => {
const wrapper = mount(MyButton, {
props: { active: true }
})
expect(wrapper.html()).toMatchSnapshot()
})
Для каждого набора props создаётся отдельный снимок. Это позволяет явно видеть, как изменение входных данных влияет на структуру DOM.
Слоты — один из самых чувствительных элементов для snapshot-подхода, так как они часто меняются. Vue Test Utils позволяет передавать содержимое слотов при монтировании.
mount(MyLayout, {
slots: {
default: '<p>Контент</p>',
footer: '<span>Футер</span>'
}
})
Snapshot фиксирует итоговый результат, включая разметку, сгенерированную самим компонентом и содержимое слотов. Это удобно для layout-компонентов и обёрток.
При наличии вложенных компонентов снимки могут быстро разрастаться и
становиться нечитаемыми. Для этого используются заглушки
(stubs).
mount(ParentComponent, {
global: {
stubs: {
ChildComponent: true
}
}
})
В snapshot вместо полного HTML дочернего компонента появится простой тег-заглушка. Это снижает шум и делает тест устойчивым к изменениям во вложенных компонентах.
Snapshot-тесты плохо сочетаются с недетерминированными значениями:
Для стабилизации используются:
jest.spyOn, vi.spyOn);Пример стабилизации даты:
jest.useFakeTimers().setSystemTime(new Date('2024-01-01'))
Без этого снимки будут постоянно меняться и терять смысл.
Изменение шаблона компонента — нормальная ситуация. В этом случае снимки обновляются вручную через тест-раннер. Однако важно понимать разницу между:
Snapshot-файлы выступают в роли контракта. Массовое обновление без анализа приводит к потере ценности тестов.
Snapshot-подход:
Точечные проверки
(expect(wrapper.find(...).exists())):
На практике snapshot-тесты применяются для:
Для логики предпочтительнее классические assert-проверки.
Распространённые подходы:
stubs.Хорошей практикой считается:
Snapshot-тесты не гарантируют корректность поведения. Они лишь фиксируют факт изменения. Компонент может рендериться стабильно, но работать неправильно.
Основные риски:
При грамотном применении snapshot-тестирование во Vue Test Utils становится мощным инструментом контроля UI-регрессий и архитектурной стабильности компонентов.