webroad.online
  1. 1Веб
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Инструменты
  8. 8React
  9. 9Стейт-менеджмент
  10. 10Next.js
  11. 11Формы
  12. 12Данные и бэкенд
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Анимации
  16. 16Тестирование
  17. 17Архитектура
Тестирование · Урок 3 из 4

Testing Library: компоненты глазами пользователя

Запросы по роли и подписи, get/query/find, user-event.

Обновлено

Что такое Testing Library

React Testing Library (RTL) — библиотека для тестирования компонентов так, как ими пользуется человек: вы находите элементы по тому, что видно (текст, подпись, роль), кликаете, печатаете — и проверяете, что появилось на экране. Внутреннее состояние и props вы не смотрите.

Её принцип: «Чем больше тесты похожи на то, как используется программа, тем больше уверенности они дают».

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

test('добавляет задачу', async () => {
  const user = userEvent.setup()
  render(<TodoApp />)

  await user.type(screen.getByLabelText('Новая задача'), 'Выучить RTL')
  await user.click(screen.getByRole('button', { name: 'Добавить' }))

  expect(screen.getByText('Выучить RTL')).toBeInTheDocument()
})

Запросы — по приоритету

Выбирайте первый из списка, который работает. Порядок отражает, насколько доступен компонент:

Приоритет Запрос Находит по Пример
1 getByRole роли + доступному имени getByRole('button', { name: 'Сохранить' })
2 getByLabelText подписи поля getByLabelText('Email')
3 getByPlaceholderText placeholder если подписи нет
4 getByText видимому тексту абзацы, сообщения
5 getByDisplayValue значению поля заполненные формы
6 getByAltText / getByTitle alt / title изображения
последний getByTestId data-testid только когда ничего другого не работает

Бонус: если элемент не находится через getByRole, чаще всего у компонента проблема с доступностью. Тесты подталкивают к лучшему HTML.

Варианты: get, query, find

Префикс Если не нашёл Async Когда
getBy бросает ошибку нет элемент должен быть сейчас
queryBy возвращает null нет проверить, что элемента нет: expect(queryByText('Ошибка')).toBeNull()
findBy бросает после таймаута да элемент появится позже (после fetch, setTimeout)

getAllBy... / queryAllBy... / findAllBy... — для нескольких элементов.

user-event или fireEvent

userEvent fireEvent
Имитирует полное взаимодействие (focus, keydown, input, keyup, click) одно DOM-событие
Реалистичность высокая низкая
Когда по умолчанию особые случаи

Чего не делать

  • Тестировать внутреннее состояние (component.state.count).
  • container.querySelector('.btn-primary') — классы это детали реализации.
  • Огромные снапшоты, которые никто не читает.

Коротко

  • RTL тестирует компоненты как пользователь: ищете по роли, подписи, тексту.
  • Приоритет: getByRole → getByLabelText → … → getByTestId.
  • get = должен быть, query = может отсутствовать, find = появится.

Официальные источники

Упражнения

Была ли страница полезной?

Один клик — без регистрации.