JavaRush /Курсы /Модуль 3: React /Основы тестирования компонентов в React — зачем тестирова...

Основы тестирования компонентов в React — зачем тестировать и какие виды тестов бывают

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

Тесты как виртуальная сетка безопасности

Всем привет На сегодняшней лекции мы переключимся с написания кода на проверку его корректности, изучая тесты. Но прежде чем мы начнем, давайте задумаемся: зачем нам это нужно? Ответ на этот вопрос прост: тесты спасают нас от непредвиденных багов.

Когда вы вносите изменения в своё приложение, можете ли вы быть уверены, что ничего не "сломали"? Тесты являются той самой "системой раннего предупреждения", которая фиксирует ошибки ДО того, как пользователи начнут на них жаловаться.

Представьте тесты как замок на вашей программе, который защищает вас от случайных ошибок, некорректных данных и последствий "я всего одну строчку поменяю".

Автоматизация и время

Тесты автоматизируют процесс проверки функциональности. Вы пишете их один раз, а потом запускаете, сколько угодно раз, когда вносите изменения. Это экономит массу времени и нервов, особенно в больших проектах.

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

Виды тестов в React

В React, как и в других технологиях, тесты делятся на несколько категорий в зависимости от их цели и уровня. Давайте рассмотрим основные из них.

1. Юнит-тесты (Unit Tests)

Юнит-тесты проверяют отдельные части приложения, как правило, функции или небольшие компоненты. В React такими "юнитами" часто являются отдельные компоненты, их пропсы, состояние или пользовательские хуки.

Давайте протестируем функциональность кнопки, чтобы убедиться, что она вызывает функцию при клике.

import { render, fireEvent } from '@testing-library/react';
import MyButton from './MyButton';

test('Should call onClick when button is clicked', () => {
  const mockHandler = jest.fn(); // создаем мокаемую функцию
  const { getByText } = render(<MyButton onClick={mockHandler} />);

  const button = getByText('Click me!');

  fireEvent.click(button); // симулируем клик

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

Применение: юнит-тесты — это "первопроходцы". Они создают основу стабильного приложения.

2. Интеграционные тесты (Integration Tests)

Интеграционные тесты проверяют взаимодействие нескольких компонентов или модулей. Здесь нас уже интересует не только конкретный компонент, но и то, как он работает вместе с другими.

Допустим, у нас есть форма, которая после ввода данных должна обновлять глобальное состояние.

import { render, fireEvent } from '@testing-library/react';
import { Provider } from 'react-redux';
import store from './store';
import MyForm from './MyForm';

test('Should update store on form submission', () => {
  const { getByLabelText, getByRole } = render(
    <Provider store={store}>
      <MyForm />
    </Provider>
  );

  fireEvent.change(getByLabelText('Name'), { target: { value: 'John' } });
  fireEvent.click(getByRole('button', { name: /submit/i }));

  expect(store.getState().user.name).toBe('John'); // проверяем обновление состояния
});

Применение: такие тесты полезны для проверки интеграции нескольких частей приложения.

3. E2E-тесты (End-to-End Tests)

End-to-End (e2e) тесты проверяют поведение приложения как единое целое. Это те тесты, которые симулируют пользователя: открывают браузер, кликают на кнопки, заполняют формы и проверяют результат.

Для e2e-тестирования часто используют инструмент Cypress.

Для примера давайте проверим авторизацию пользователя через интерфейс:

describe('Login page tests', () => {
  it('Should log in the user', () => {
    cy.visit('/login'); // Открываем страницу логина
    cy.get('input[name="username"]').type('testUser'); // Вводим имя пользователя
    cy.get('input[name="password"]').type('password123'); // Вводим пароль
    cy.contains('button', 'Login').click(); // Нажимаем на кнопку входа

    cy.url().should('eq', '/dashboard'); // Убедимся, что пользователь перенаправлен на дашборд
  });
});

Применение: такие тесты полезны для проверки конечного пользовательского опыта.

Какой тип тестов выбрать?

Все три категории тестов важны и, по идее, должны сосуществовать в рамках одного приложения. Но реальные проекты требуют баланса:

  • Юнит-тесты: их надо писать много. Они быстрые и локализованные, охватывают основную функциональность.
  • Интеграционные тесты: их надо немного меньше. Они медленнее, но проверяют, как компоненты взаимодействуют друг с другом.
  • E2E-тесты: они медленные и сложные в обслуживании. Добавляйте их только для критически важного функционала (например, авторизация, покупки).

Практическое применение: тесты на реальных проектах

Тестирование — это не просто способ проверить свой код. Это ещё и довод на собеседовании. Когда вас спрашивают: "Как вы обеспечиваете качество кода?", вы уверенно говорите: "Я пишу тесты".

В реальных проектах:

  • Юнит-тесты помогают обнаружить ошибки ещё на этапе разработки.
  • Интеграционные тесты предотвращают проблемы во взаимодействии модулей.
  • E2E-тесты обеспечивают уверенность, что пользовательский интерфейс работает корректно.

А ещё они избавляют вас от страха: "Я закоммитил, и CI/CD выгрузил это в продакшн. Надеюсь, ничего не сломал..."

Типичные возражения против тестирования

Каждый программист рано или поздно сталкивается с внутренним (или внешним) сопротивлением.

"Тесты занимают слишком много времени"

Сначала — да, но с опытом вы начнёте писать их быстрее. А время, сэкономленное на поиске багов в будущем, окупает всё.

"Зачем писать тесты, если код рабочий?"

Код может быть рабочим сейчас, но что будет через три месяца, когда другой программист изменит его? Тесты — это ваша страховка.

"E2E-тесты слишком медленные"

Да, но они проверяют весь путь пользователя. И с этим сложно спорить.

Таким образом, тестирование — это не просто "лишняя работа", это инвестиция в качество вашего кода. А какие виды тестов использовать, зависит от ваших целей, задач и, конечно же, требований проекта. В следующей лекции мы установим инструменты для тестирования в вашем проекте, чтобы перейти от теории к практике.

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