Тестування Vue-компонентів з Vue Test Utils
Ви оновили компонент кошика, а в продакшені — помилка: кількість товарів не перераховується. Без unit-тестів ви дізнаєтеся про баги від користувачів, а пошук причини займає години. Vue Test Utils — офіційна бібліотека для тестування Vue 3 компонентів — вирішує цю проблему: ізольоване монтування, імітація подій, перевірка реактивності без запуску всього застосунку. Ми, команда TrueTech, налаштовуємо повний цикл тестування під ключ: від вибору стеку до CI-пайплайну. Гарантуємо покриття ключових сценаріїв і навчання команди, спираючись на 5+ років досвіду роботи з Vue екосистемою та понад 50 впроваджених проєктів.
Зв'яжіться з нами, щоб оцінити поточне покриття та обрати стратегію тестування.
Чому варто автоматизувати тестування Vue-компонентів?
Перевіряти кожен компонент вручну перед релізом — довго та ненадійно. Unit-тести автоматизують перевірку: рендер, еміти, стан, edge-кейси. Згідно з офіційною документацією Vue Test Utils, бібліотека призначена для ізольованого тестування компонентів. Vue Test Utils у зв'язці з Vitest працює в 5 разів швидше за Cypress Component Test Runner для простих сценаріїв — не потрібен браузер. Тести запускаються локально та в CI, даючи швидкий зворотний зв'язок розробникам. Регресійне тестування прискорюється на 80%, а час пошуку багів скорочується на 30% — це підтверджує практика наших проєктів. В одному з проєктів ми скоротили час регресійного прогону з 3 годин до 30 хвилин (у 6 разів).
Як налаштувати тестування Vue 3 з Vue Test Utils?
Покрокова інструкція налаштування
-
Встановіть залежності:
npm install -D @vue/test-utils vitest jsdom. - Створіть vitest.config.ts із запропонованою конфігурацією:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
test: {
environment: 'jsdom',
globals: true,
},
});
- Напишіть перший тест. Приклад перевірки рендера та еміту:
import { mount } from '@vue/test-utils';
import UserCard from './UserCard.vue';
describe('UserCard', () => {
it('renders user name', () => {
const wrapper = mount(UserCard, {
props: { user: { name: 'Іван Петров', email: '[email protected]' } },
});
expect(wrapper.text()).toContain('Іван Петров');
});
it('emits delete event with user id', async () => {
const wrapper = mount(UserCard, {
props: { user: { id: 42, name: 'Іван' } },
});
await wrapper.find('[data-testid="delete-btn"]').trigger('click');
expect(wrapper.emitted('delete')).toBeTruthy();
expect(wrapper.emitted('delete')![0]).toEqual([42]);
});
});
- Запустіть тести:
npx vitest.
Які сценарії покривають unit-тести?
Тестування взаємодії зі сховищем. Якщо компонент залежить від Pinia, перед кожним тестом ініціалізуйте сховище:
import { setActivePinia, createPinia } from 'pinia';
import { useCartStore } from '@/stores/cart';
describe('CartButton', () => {
beforeEach(() => setActivePinia(createPinia()));
it('adds item to cart', async () => {
const wrapper = mount(CartButton, {
props: { productId: 1 },
global: { plugins: [createPinia()] },
});
const store = useCartStore();
await wrapper.find('button').trigger('click');
expect(store.items).toHaveLength(1);
});
});
Асинхронне завантаження даних. Використовуйте vi.mock() та flushPromises() для мока API:
it('loads data after API call', async () => {
vi.mock('@/api', () => ({
fetchUser: vi.fn().mockResolvedValue({ name: 'Марія' }),
}));
const wrapper = mount(UserProfile, { props: { userId: 1 } });
expect(wrapper.find('[data-testid="loading"]').exists()).toBe(true);
await flushPromises();
expect(wrapper.text()).toContain('Марія');
});
Слоти та стаби. Перевірте рендер слотів та ізолюйте дочірні компоненти через shallowMount:
it('renders default slot', () => {
const wrapper = mount(Card, {
slots: { default: '<p data-testid="slotted">Вміст</p>' },
});
expect(wrapper.find('[data-testid="slotted"]').exists()).toBe(true);
});
it('uses shallowMount to stub children', () => {
const wrapper = shallowMount(ParentComponent);
// дочірні компоненти автоматично стабуються
});
Composables тестуються без монтування — просто викликайте функцію та перевіряйте результат. Наприклад, для хуку валідації форми: передайте поля, викличте validate() і перевірте помилки.
Як уникнути типових помилок при написанні тестів?
- Не забувайте скидати стан Pinia в
beforeEach:setActivePinia(createPinia()). Інакше тести впливатимуть один на одного. - Для асинхронних операцій завжди використовуйте
flushPromises()після мока, інакше тест може завершитися до виконання. - Використовуйте
data-testidатрибути для пошуку елементів — це стабільніше, ніж CSS-класи або текст. - При тестуванні слотів не забувайте передавати контент через
slots: { default: '...' }.
Чек-лист налаштування середовища
- Встановлено @vue/test-utils, vitest, jsdom
- Конфігурація vitest включає jsdom та globals
- Написано хоча б один тест для перевірки зв'язки
- Тести запускаються локально
npx vitest - Тести інтегровані в CI (наприклад, GitHub Actions)
Налаштування тестування під ключ: що входить
- Аналіз поточного проекту та вибір стеку (Vitest + Vue Test Utils або Jest).
- Налаштування віртуального середовища (jsdom) та конфігурації vitest.
- Написання тестів для 20–30 ключових компонентів: монтування, події, стани, асинхронні операції.
- Створення моків для API та сховищ.
- Інтеграція тестів в CI (GitLab CI / GitHub Actions / Bitbucket Pipelines).
- Документація з написання нових тестів та метрикам покриття.
- Навчання команди: 2-годинний воркшоп з написання unit-тестів.
Порівняння методів тестування Vue-компонентів
| Метод | Швидкість | Ізоляція | Перевірка UI | Ресурси |
|---|---|---|---|---|
| Unit (Vue Test Utils) | Висока | Повна | Логічна | Низькі |
| Компонентне (Cypress) | Середня | Часткова | Візуальна | Високі |
| E2E (Playwright) | Низька | Немає | Повна | Дуже високі |
Етапи налаштування тестування під ключ
| Етап | Тривалість | Результат |
|---|---|---|
| Аналіз та вибір стеку | 1 день | План тестування |
| Налаштування середовища | 1 день | Робочий vitest + jsdom |
| Написання тестів (20–30 компонентів) | 2–4 дні | Набір тестів з покриттям |
| Інтеграція в CI | 1 день | Автозапуск при пуші |
| Документація та навчання | 1 день | Гайд та воркшоп |
Строки реалізації
Налаштування середовища, написання тестів та інтеграція в CI для типового Vue-проекту займають від 4 до 7 днів. Точна оцінка залежить від складності компонентів та обсягу legacy-коду.
Отримайте консультацію з тестування вашого Vue-проекту — ми оцінимо поточне покриття, допоможемо обрати стратегію та налаштуємо швидкий пайплайн. Досвід роботи з Vue — 5+ років, десятки проектів з високою складністю. Гарантуємо якість та прозорість процесу. Зв'яжіться з нами, щоб обговорити деталі.







