Пошук уроків, статей та іншого контенту
Налаштуєте Vitest для React-проєкту та створите перші тести з описом сценаріїв і перевірками.
Vitest — це швидкий тестувальник для проєктів на Vite. Він добре працює з React і підтримує знайомий синтаксис describe, it, expect.
У цьому уроці ми:
встановимо Vitest та інструменти для тестування React;
налаштуємо середовище браузера через jsdom;
створимо компонент;
напишемо перші тести;
запустимо тести в одноразовому та інтерактивному режимах.
Припустімо, що у вас уже є React-проєкт, створений за допомогою Vite. У корені проєкту встановіть залежності:
npm install -D vitest jsdom @testing-library/react @testing-library/jest-domПакети потрібні для таких завдань:
vitest — запуск і виконання тестів;
jsdom — імітація браузерного середовища в Node.js;
@testing-library/react — рендеринг React-компонентів і пошук елементів;
@testing-library/jest-dom — додаткові перевірки для DOM, наприклад toBeInTheDocument().
Відкрийте файл конфігурації Vite. Зазвичай це vite.config.js або vite.config.jsx.
Додайте до нього секцію test:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
setupFiles: './src/test/setup.js',
},
});environment: 'jsdom' вказує Vitest використовувати браузероподібне середовище. Завдяки цьому в тестах доступні document, window та інші DOM-об'єкти.
setupFiles містить файл, який Vitest запускає перед тестами. У ньому підключимо додаткові DOM-перевірки.
Створіть файл src/test/setup.js:
import '@testing-library/jest-dom/vitest';Після цього в тестах можна буде використовувати такі перевірки:
toBeInTheDocument();
toBeVisible();
toHaveTextContent();
toBeDisabled().
У файлі package.json додайте команди до властивості scripts:
{
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "vitest run",
"test:watch": "vitest"
}
}Команда test запускає всі тести один раз.
Команда test:watch запускає Vitest в інтерактивному режимі. Після зміни файлів тести запускатимуться повторно.
Створимо простий компонент Greeting, який показує привітання та змінює текст після натискання кнопки.
Файл src/components/Greeting.jsx:
import { useState } from 'react';
export function Greeting({ name }) {
const [isWelcomed, setIsWelcomed] = useState(false);
return (
<section>
<h1>Привіт, {name}!</h1>
<button type="button" onClick={() => setIsWelcomed(true)}>
Привітатися
</button>
{isWelcomed && <p role="status">Раді вас бачити!</p>}
</section>
);
}Компонент має два сценарії:
На початку відображається заголовок і кнопка.
Після натискання кнопки з'являється повідомлення.
Саме ці сценарії ми перевіримо в тестах.
Файл тесту зазвичай має суфікс .test.js, .test.jsx, .spec.js або .spec.jsx.
Наприклад:
src/
├── components/
│ ├── Greeting.jsx
│ └── Greeting.test.jsx
└── test/
└── setup.jsУ тесті найчастіше використовують такі функції:
describe — групує тести, пов'язані з одним компонентом або функцією;
it або test — описує один конкретний сценарій;
expect — перевіряє очікуваний результат.
Створіть файл src/components/Greeting.test.jsx:
import { describe, expect, it } from 'vitest';
import { fireEvent, render, screen } from '@testing-library/react';
import { Greeting } from './Greeting';
describe('Greeting', () => {
it('показує привітання з іменем користувача', () => {
render(<Greeting name="Олена" />);
expect(
screen.getByRole('heading', { name: 'Привіт, Олена!' }),
).toBeInTheDocument();
expect(
screen.getByRole('button', { name: 'Привітатися' }),
).toBeInTheDocument();
});
it('показує повідомлення після натискання кнопки', () => {
render(<Greeting name="Олена" />);
expect(
screen.queryByRole('status'),
).not.toBeInTheDocument();
fireEvent.click(
screen.getByRole('button', { name: 'Привітатися' }),
);
expect(
screen.getByRole('status', { name: 'Раді вас бачити!' }),
).toBeInTheDocument();
});
});Спочатку викликається render:
render(<Greeting name="Олена" />);Він створює React-компонент у тестовому DOM.
Після цього screen допомагає знайти елементи, доступні користувачу:
screen.getByRole('button', { name: 'Привітатися' });Такий пошук перевіряє роль елемента і його доступне ім'я. Для кнопки доступним ім'ям є текст Привітатися.
У першому тесті ми перевіряємо початковий стан компонента:
заголовок містить ім'я користувача;
кнопка відображається.
У другому тесті перевіряємо взаємодію:
повідомлення спочатку відсутнє;
відбувається натискання кнопки;
повідомлення з'являється.
Testing Library надає кілька основних методів:
getByRoleПовертає елемент, якщо його знайдено. Якщо елемента немає, тест завершується помилкою.
screen.getByRole('button', { name: 'Привітатися' });Цей метод варто використовувати для елементів, які повинні бути присутніми.
queryByRoleПовертає елемент або null, якщо елемент не знайдено.
screen.queryByRole('status');Цей метод зручно використовувати, коли потрібно перевірити відсутність елемента:
expect(screen.queryByRole('status')).not.toBeInTheDocument();getByTextШукає елемент за текстом:
screen.getByText('Раді вас бачити!');Для інтерактивних елементів перевагу краще надавати пошуку за роллю:
screen.getByRole('button', { name: 'Привітатися' });Так тест ближчий до того, як користувач взаємодіє зі сторінкою.
Запустіть тести один раз:
npm testАбо безпосередньо:
npm run testЯкщо всі перевірки успішні, Vitest покаже кількість пройдених тестів.
Для режиму спостереження використовуйте:
npm run test:watchУ цьому режимі Vitest залишатиметься запущеним і повторно виконуватиме тести після змін у файлах. Щоб завершити роботу, натисніть Ctrl + C.
Назва тесту має пояснювати очікувану поведінку, а не внутрішню реалізацію компонента.
Добре:
it('показує повідомлення після натискання кнопки', () => {
// перевірки
});Гірше:
it('змінює значення стану isWelcomed', () => {
// перевірки
});Користувач не бачить назву стану isWelcomed. Він бачить повідомлення після натискання кнопки. Тому тест краще описувати з погляду поведінки інтерфейсу.
jsdomЯкщо в конфігурації немає:
environment: 'jsdom'під час рендерингу компонента можуть виникнути помилки, пов'язані з відсутністю document або window.
jest-domЯкщо не створити файл налаштування або не додати імпорт:
import '@testing-library/jest-dom/vitest';перевірка toBeInTheDocument() не працюватиме.
getBy... для перевірки відсутностіМетоди getBy... викидають помилку, якщо елемент відсутній. Для перевірки відсутності використовуйте queryBy...:
expect(screen.queryByRole('status')).not.toBeInTheDocument();Не потрібно перевіряти, чи використав компонент конкретний хук або певну назву змінної. Перевіряйте видиму поведінку:
що відображається;
що зникає;
як змінюється інтерфейс після дії користувача.
renderПеред пошуком елементів компонент потрібно відрендерити:
render(<Greeting name="Олена" />);Без цього screen не матиме змонтованого компонента для перевірки.
Vitest використовується для запуску тестів у React-проєкті.
Для тестування DOM потрібно налаштувати середовище jsdom.
@testing-library/react дозволяє рендерити компоненти та знаходити їхні елементи.
describe групує тести, it описує сценарій, а expect перевіряє результат.
getByRole підходить для пошуку наявних елементів.
queryByRole зручно використовувати для перевірки відсутності елементів.
Хороший тест описує поведінку компонента з погляду користувача.
Команда npm test запускає тести один раз, а npm run test:watch — у режимі спостереження.