Інструменти та стандарти середовища
Тест-раннер — Vitest
Section titled “Тест-раннер — Vitest”Чому Vitest:
-
Єдиний стандарт для всіх типів проєктів. Vitest однаково добре працює в - Next.js, Astro, Nest.js, Hono, Vanilla / jQuery.
-
Повна сумісність із Node.js. Vitest працює поверх Node runtime, без симуляцій або несумісностей. Це гарантує, що поведінка коду у тестах = поведінка у продакшні (на відміну від Bun, який має свій runtime).
-
Висока швидкість. Vitest використовує архітектуру Vite:
- запуск в ESM середовищі без транспайлерів;
- кешування результатів;
- миттєвий watch-режим;
У більшості проєктів швидкість виконання тестів у 2–5 разів вища за Jest.
-
Нативна підтримка TypeScript і JSX. Жодних ts-jest, Babel чи SWC-конфігів. Vitest напряму компілює TypeScript і JSX через Vite.
-
Універсальне середовище тестування.
Можна обратиenvironment: 'node'для бекенду (Nest.js, Hono) абоenvironment: 'jsdom'для UI-тестів (Next.js, Astro, jQuery) -
Вбудовані репорти для CI/CD. Vitest підтримує:
- JUnit для GitLab / Jenkins / GitHub Actions;
- Coverage (Istanbul) з текстовими, HTML, LCOV звітами;
- Exit code management (pipeline падає при фейлах);
- Мінімальні пороги coverage прямо в конфігу;
-
Моки, сніпшоти, таймери — усе з коробки. Немає потреби ставити sinon чи chai. Vitest має:
-
vi.fn(),vi.spyOn(),vi.mock()— для моків; -
vi.useFakeTimers()— для таймерів; -
expect(...).toMatchSnapshot()— для snapshot-тестів;
Повний набір можливостей без зайвих залежностей.
-
Сильна екосистема і спільнота. Vitest — частина екосистеми Vite, яку активно підтримують Evan You (Vue), Anthony Fu (UnoCSS, Slidev) та інші топ-розробники. Постійні оновлення, сумісність із найновішими версіями Node, TS і фреймворків.
-
Простота онбордингу. API і синтаксис повністю сумісні з Jest (describe, it, expect), тому:
-
легко мігрувати старі тести;
-
нові розробники миттєво розуміють структуру;
-
Мінімальний maintenance.
-
Не потребує Babel чи додаткових трансформерів.
-
Легко оновлюється, не ламає конфіги при мажорних апдейтах.
-
Працює з будь-яким package manager’ом (pnpm, yarn, npm).
Стандартна версія:
vitest >=4.0vite >=6.0- середовище
Node.js ≥ 22.x (LTS) pnpmяк package manager
Тестова бібліотека
Section titled “Тестова бібліотека”Основні модулі:
@testing-library/react— рендеринг компонентів і пошук елементів за ролями, текстами тощо.@testing-library/user-event— симуляція взаємодій (кліки, введення, таби, клавіатура).@testing-library/jest-dom/vitest— набір розширених матчів (toBeInTheDocument,toHaveTextContent,toBeDisabledтощо).
Моки мережі — MSW
Section titled “Моки мережі — MSW”Навіщо: для симуляції API-відповідей у тестах без реального бекенду.
- Працює в jsdom як “in-memory” HTTP-інтерцептор.
- Дозволяє створювати обробники (handlers) для REST або GraphQL-запитів.
- Повністю відтворює очікувану поведінку: заголовки, статуси, таймаути.
- Забезпечує однакові тести локально, у CI та в браузері.
Типові сценарії:
- UI-компоненти, що викликають API;
- хуки, які фетчать дані (
useQuery,useFetchData); - тестування поведінки при 404 / 500 статусах.
Використання з Vitest
Section titled “Використання з Vitest”У тестах використовуємо Node-версію — setupServer.
Створюємо інтерсептори
import { http, HttpResponse } from 'msw'
export const handlers = [ http.get('/api/user', () => { return HttpResponse.json({ id: 1, name: 'Some Name' }) }),}),...]Налаштовуємо Vitest
import { setupServer } from 'msw/node'import { handlers } from '../src/mocks/handlers'
export const server = setupServer(...handlers)
beforeAll(() => server.listen())afterEach(() => server.resetHandlers())afterAll(() => server.close())Середовище виконання
Section titled “Середовище виконання”Vitest підтримує два основних середовища:
| Середовище | Призначення | Коли використовувати |
|---|---|---|
| jsdom | емуляція браузера | для React-компонентів, хуків із DOM-ефектами |
| node | нативне Node-оточення | для утиліт, SDK, API-клієнтів, скриптів |
У нашій політиці:
- jsdom використовується за замовчуванням (
environment: 'jsdom'); - файли
*.node.test.tsавтоматично запускаються у node-режимі (див.vitest.config.ts).
import { defineConfig } from 'vitest/config'import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({plugins: [tsconfigPaths()],test: { globals: true, include: ['**/*.test.{ts,tsx}'], // базова маска environment: 'jsdom', setupFiles: ['./setupTests.ts'],},// окремі проекти з власним середовищемprojects: [ // 1. jsdom (за замовчуванням — для React, UI) { test: { name: 'jsdom', environment: 'jsdom', include: ['**/*.test.{ts,tsx}'], exclude: ['**/*.node.test.{ts,tsx}'], }, }, // 2. node (для SDK, утиліт, API) { test: { name: 'node', environment: 'node', include: ['**/*.node.test.{ts,tsx}'], }, },],})Глобальні налаштування
Section titled “Глобальні налаштування”setupTests.ts Цей файл виконується перед кожним тестом і:
- реєструє матчери (
@testing-library/jest-dom/vitest); - очищає DOM після кожного тесту (
cleanup()); - додає моки для відсутніх у jsdom API (
matchMedia,ResizeObserver,IntersectionObserver…); - налаштовує поведінку
console.error/console.warn(щоб тест падав, якщо компонент викидає помилку); - підключає MSW-сервер;
Звіти та покриття
Section titled “Звіти та покриття”- Покриття генерується за допомогою V8 Coverage Provider (
coverage.provider: 'v8'). - Формати репортів:
text,html,lcov,json-summary,cobertura. - Звіти зберігаються у
reports/coverageі передаються у CI як артефакти. - Для GitLab використовується
junit-репортер (reports/junit-unit.xml) — дані автоматично потрапляють у Merge Request.
Менеджер пакетів
Section titled “Менеджер пакетів”Стандарти:
pnpm >=10.x— швидкий, ізольований, з кращим кешуваннямnode_modules.- Алиаси
@/мають бути синхронізовані зtsconfig.jsonчерез плагінvite-tsconfig-paths.
Інші рекомендовані пакети
Section titled “Інші рекомендовані пакети”| Пакет | Призначення |
|---|---|
| whatwg-fetch | поліфіл fetch у jsdom |
| faker-js/faker | генерація фіктивних даних |
| @anatine/zod-mock | автоматичні фікстури зі схем Zod |
| msw/node | емуляція мережі у Node-середовищі |
| vitest-axe | a11y-перевірки через axe-core (опціонально) |
Стандарти середовища
Section titled “Стандарти середовища”Щоб тести працювали однаково у всіх середовищах (локально, CI, staging):
| Параметр | Значення | Примітка |
|---|---|---|
| Node.js | ≥ 22.x | однакова версія у локальних та CI-середовищах |
| Timezone | UTC | фіксований, щоб уникнути розбіжностей у датах |
| Locale | en-US | стабільна локаль для форматів чисел/дат |
| Browser API mocks | однакові у всіх (через setupTests.ts) | matchMedia, ResizeObserver, IntersectionObserver |
| ENV | .env.test | ізольований набір змінних (жодних продакшн-ключів) |