JavaRush /Курсы /Модуль 3: React /Тестирование событий пользователя — клики, ввод текста, ф...

Тестирование событий пользователя — клики, ввод текста, фокус

Модуль 3: React
17 уровень , 4 лекция
Открыта

Почему важно тестировать события пользователя?

Наши приложения — это не скучный статичный HTML. Их оживляют клики, набор текста, фокус. Поэтому важно убедиться, что всё это работает корректно, иначе пользователь, не получив ожидаемого результата, просто закроет вкладку и уйдёт.

Представьте: вы создали кнопку "Удалить всё", но из-за ошибки нажатие на неё делает что-то совершенно непредсказуемое, например, заказывает пиццу вашему начальнику. Тестируя пользовательские события, мы убеждаемся, что наше приложение реагирует на действия так, как задумано, без сюрпризов.

Основные инструменты: React Testing Library и fireEvent

Для тестирования взаимодействий мы будем использовать библиотеку React Testing Library и её инструмент fireEvent. React Testing Library предоставляет простую и понятную абстракцию для симуляции пользовательских действий, а fireEvent позволяет "прикидываться" пользователем, который кликает, вводит текст или перемещает фокус.

Мы будем использовать такие етоды из fireEvent:

  • fireEvent.click — симулирует клик по элементу.
  • fireEvent.change — имитирует ввод данных в инпут или textarea.
  • fireEvent.focus и fireEvent.blur — для проверки реакций на установку или потерю фокуса.

Давайте начнём с простого компонента для тестирования пользовательских взаимодействий:

// components/UserForm.tsx
import React, { useState } from "react";

interface UserFormProps {
  onSubmit: (name: string) => void;
}

export const UserForm: React.FC<UserFormProps> = ({ onSubmit }) => {
  const [name, setName] = useState("");

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    onSubmit(name);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="name">Name:</label>
      <input
        id="name"
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        data-testid="name-input"
      />
      <button type="submit" data-testid="submit-button">
        Submit
      </button>
    </form>
  );
};

Этот компонент состоит из текстового поля, кнопки и простого обработчика формы. При нажатии на кнопку вызывается переданная через пропс onSubmit функция.

Тестирование кликов

Начнём с тестирования кликов по кнопке в нашей форме.

// tests/UserForm.test.tsx
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { UserForm } from "../components/UserForm";

test("отправка формы при клике на кнопку", () => {
  const mockOnSubmit = jest.fn(); // имитация переданной функции
  render(<UserForm onSubmit={mockOnSubmit} />);

  const button = screen.getByTestId("submit-button");
  fireEvent.click(button);

  expect(mockOnSubmit).toHaveBeenCalled(); // проверяем, что функция была вызвана
});

В этом тесте мы проверяем, вызывается ли переданная функция onSubmit при клике на кнопку. Для этого используем jest.fn() — мок-функцию, которая позволяет отслеживать вызовы.

Тестирование ввода текста

Теперь протестируем, как наш компонент обрабатывает ввод текста в поле. Мы будем использовать fireEvent.change.

test("обновление состояния при вводе текста", () => {
  const mockOnSubmit = jest.fn();
  render(<UserForm onSubmit={mockOnSubmit} />);

  const input = screen.getByTestId("name-input");
  fireEvent.change(input, { target: { value: "John Doe" } });

  expect(input).toHaveValue("John Doe"); // проверяем, что значение обновилось
});

В данном тесте fireEvent.change имитирует ввод текста "John Doe". После этого мы проверяем, что значение инпута действительно изменилось, используя метод toHaveValue.

Тестирование фокуса

Фокусировка элементов интерфейса играет большую роль в доступности приложения. Проверим, корректно ли компонент реагирует на установку и потерю фокуса.

Мы добавим простую визуальную реакцию на фокус в компонент:

// Update in UserForm.tsx
const [isFocused, setIsFocused] = useState(false);

return (
  <form onSubmit={handleSubmit}>
    <label htmlFor="name">Name:</label>
    <input
      id="name"
      type="text"
      value={name}
      onChange={(e) => setName(e.target.value)}
      onFocus={() => setIsFocused(true)}
      onBlur={() => setIsFocused(false)}
      data-testid="name-input"
    />
    {isFocused && <p data-testid="focus-message">Input is focused</p>}
    <button type="submit" data-testid="submit-button">
      Submit
    </button>
  </form>
);

Новый тест на проверку фокуса:

test("проверка установки и потери фокуса", () => {
  const mockOnSubmit = jest.fn();
  render(<UserForm onSubmit={mockOnSubmit} />);

  const input = screen.getByTestId("name-input");

  fireEvent.focus(input);
  expect(screen.getByTestId("focus-message")).toBeInTheDocument();

  fireEvent.blur(input);
  expect(screen.queryByTestId("focus-message")).not.toBeInTheDocument();
});

Мы используем fireEvent.focus, чтобы проверить появление текста "Input is focused". Затем, применяя fireEvent.blur, убеждаемся, что текст исчезает.

Типичные ошибки при тестировании событий

Тестирование событий пользователя может столкнуться с рядом подводных камней. Например, если вы забудете явно указать значения в объекте target при изменении данных с помощью fireEvent.change, то тест будет вести себя странно и не отразит реальных результатов.

Ещё одна ошибка — неверная цель. Убедитесь, что вы используете корректные селекторы, такие как getByTestId, чтобы находить нужные элементы. Например, использование getByText для элементов, которые могут изменять своё текстовое содержимое в процессе теста, не всегда надёжно.

2
Задача
Модуль 3: React, 17 уровень, 4 лекция
Недоступна
Тестирование клика по кнопке
Тестирование клика по кнопке
3
Опрос
Тестирование компонентов с Jest, 17 уровень, 4 лекция
Недоступен
Тестирование компонентов с Jest
Тестирование компонентов с Jest
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ