Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Який підхід до тестування пропонує React Testing Library і чому шукати елементи за роллю?

React Testing Library побудована на принципі: чим більше тести схожі на те, як застосунок використовують, тим більше впевненості вони дають. Тест взаємодіє з компонентом як користувач - бачить текст і кнопки, натискає, вводить, - а не перевіряє стан, props чи внутрішні методи.

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('додає товар у кошик', async () => {
  const user = userEvent.setup();
  render(<Product product={{ id: 1, title: 'Чашка', price: 250 }} />);

  await user.click(screen.getByRole('button', { name: 'Додати в кошик' }));

  expect(screen.getByRole('status')).toHaveTextContent('У кошику: 1');
});

Пріоритет запитів (від кращого до гіршого):

  1. getByRole з name - роль доступності (кнопка, посилання, поле, заголовок) і доступна назва. Так елементи знаходять і користувачі зчитувачів екрана;
  2. getByLabelText - поля форми за підписом;
  3. getByPlaceholderText, getByText, getByDisplayValue;
  4. getByAltText, getByTitle;
  5. getByTestId - лише коли інших способів немає.

Чому роль, а не клас чи data-testid:

  • тест не ламається від рефакторингу: змінили розмітку, класи Tailwind, структуру - тест проходить, поки кнопка лишається кнопкою з тим самим текстом;
  • тест перевіряє доступність: якщо кнопку зробили <div onClick>, getByRole('button') її не знайде - і це правильно, бо клавіатурою та зчитувачем екрана її теж не використати;
  • getByLabelText падає, якщо поле не пов'язане з підписом, - ще одна безкоштовна перевірка.

Варіанти запитів:

  • getBy... - елемент має бути, інакше помилка;
  • queryBy... - повертає null, для перевірки відсутності (expect(screen.queryByText('Помилка')).not.toBeInTheDocument());
  • findBy... - чекає на появу (асинхронно);
  • getAllBy... тощо - кілька елементів.

screen замість деструктуризації результату render - коротше й не треба оновлювати деструктуризацію.

Налагодження: screen.debug() друкує поточний DOM, а screen.logTestingPlaygroundURL() дає посилання, де можна підібрати найкращий запит для елемента.

Докладніше в документації: Testing Library: пріоритет запитів

Схожі питання