Работа с формами в React часто подразумевает использование checkboxes и radio buttons для выбора нескольких или единственного значения. Правильное тестирование этих элементов обеспечивает надежность интерфейса и корректную обработку пользовательских действий.
React Testing Library ориентирована на взаимодействие с DOM так, как это делает пользователь. Для поиска чекбоксов и радиокнопок применяются методы:
getByRole('checkbox', { name: /название/i })getByRole('radio', { name: /название/i })getByLabelText(/метка/i)Использование роли предпочтительно, так как она учитывает доступность
элемента, а getByLabelText связывает тест с визуальной
меткой, что повышает читаемость.
const checkbox = screen.getByRole('checkbox', { name: /согласие/i });
const radioOption = screen.getByLabelText(/мужской/i);
Для чекбоксов важно тестировать выбранное/невыбранное состояние:
expect(checkbox).not.toBeChecked(); // элемент не выбран
fireEvent.click(checkbox);
expect(checkbox).toBeChecked(); // элемент выбран после клика
Для радиокнопок проверяется, что только одна кнопка в группе может быть выбрана:
const maleRadio = screen.getByLabelText(/мужской/i);
const femaleRadio = screen.getByLabelText(/женский/i);
fireEvent.click(maleRadio);
expect(maleRadio).toBeChecked();
expect(femaleRadio).not.toBeChecked();
fireEvent.click(femaleRadio);
expect(femaleRadio).toBeChecked();
expect(maleRadio).not.toBeChecked();
userEvent вместо fireEventuserEvent имитирует поведение пользователя более
реалистично, учитывая события pointer, focus и
change:
import userEvent from '@testing-library/user-event';
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
await userEvent.click(femaleRadio);
expect(femaleRadio).toBeChecked();
expect(maleRadio).not.toBeChecked();
Часто необходимо проверить набор чекбоксов:
const options = screen.getAllByRole('checkbox');
await userEvent.click(options[0]);
await userEvent.click(options[2]);
expect(options[0]).toBeChecked();
expect(options[1]).not.toBeChecked();
expect(options[2]).toBeChecked();
Такой подход позволяет убедиться, что выбор нескольких элементов работает независимо.
Важно удостовериться, что onChange вызывается корректно:
const handleChange = jest.fn();
render(<input type="checkbox" onCha nge={handleChange} />);
await userEvent.click(screen.getByRole('checkbox'));
expect(handleChange).toHaveBeenCalledTimes(1);
Для радиокнопок тест аналогичен:
const handleRadioChange = jest.fn();
render(
<>
<input type="radio" value="a" name="group" onCha nge={handleRadioChange} />
<input type="radio" value="b" name="group" onCha nge={handleRadioChange} />
</>
);
await userEvent.click(screen.getByDisplayValue('b'));
expect(handleRadioChange).toHaveBeenCalledTimes(1);
Если выбор чекбокса или радиокнопки запускает асинхронное действие
(например, загрузку данных), необходимо использовать
waitFor:
await userEvent.click(checkbox);
await waitFor(() => expect(screen.getByText(/загрузка завершена/i)).toBeInTheDocument());
Это гарантирует, что тест не завершится до выполнения всех обновлений состояния.
Checkboxes и radio buttons должны иметь корректные метки
(label) для обеспечения доступности. Тесты через
getByLabelText одновременно проверяют и эту
доступность.
const checkbox = screen.getByLabelText(/принимаю условия/i);
expect(checkbox).toBeInTheDocument();
Для ясности тесты обычно структурируют по сценариям:
Это упрощает поддержку и делает тесты читаемыми.
checked.waitFor для
корректного ожидания изменений.Эти подходы делают тесты надежными, доступными и максимально приближенными к реальному поведению пользователей.