Написание тестов в React имеет решающее значение для обеспечения того, чтобы приложения работали должным образом, выявляя ошибки на ранних этапах цикла разработки и снижая общую стоимость исправления проблем.
Тесты также обеспечивают уверенность в качестве кодовой базы, упрощая ее сопровождение и рефакторинг. Тестируя код, разработчики могут убедиться, что он соответствует требованиям и спецификациям приложения, и определить области, которые могут нуждаться в улучшении или оптимизации.
В целом, тесты являются важным компонентом процесса разработки программного обеспечения, повышая качество и надежность приложений React.
Я создал шпаргалку по Основам тестирования React, не стесняйтесь скачать ее.
Типы тестов
Это множество различных типов тестов в любом серьезном программном проекте.
- Модульные тесты проверяют функциональность отдельных модулей или модулей кода. Во многих проектах вам потребуется 80% всех ваших тестов, написанных в модульных тестах.
- Интеграционные тесты проверяют взаимодействие между различными единицами или модулями кода. Еще 15% — 20% на интеграционные тесты.
- Сквозные тесты проверяют функциональность всей системы или приложения. Поскольку сквозные тесты реальны, то есть для них требуется много ресурсов, а поскольку они подключают настоящие компоненты (базу данных, сеть и сторонние сервисы), они дороги, хрупки и должны использоваться только в большинстве случаев. критические пути. Обычно у вас не будет слишком много тестов (около 5%).
Больше информации о тестовой пирамиде можно найти в этой фантастической статье. В этой статье я хотел бы обсудить некоторые фундаментальные аспекты написания тестов. Здесь я в основном сосредоточусь на модульных тестах, хотя считаю, что интеграционные и сквозные тесты не менее важны.
Прежде чем погрузиться в тестирование, давайте согласуем некоторые основные термины.
Тестовый бегун
Средство запуска тестов — это инструмент, который выполняет автоматизированные тесты, написанные для программного приложения, и сообщает результаты пользователю. Он предоставляет среду для запуска тестов и сбора результатов тестов. Средства выполнения тестов можно настроить для запуска различных типов тестов, таких как модульные тесты, интеграционные тесты и сквозные тесты.
Таким образом, исполнитель тестов может планировать и запускать тесты параллельно, гарантируя, что функции настройки и демонтажа будут вызываться в нужное время и т. д. Кроме того, вы можете настроить их только для запуска небольшого подмножества ваших тестов, что полезно для более крупный проект, содержащий тысячи тестов.
Некоторые известные средства запуска тестов для приложений JavaScript и React включают Jest, Mocha и Cypress.
Тестирование
В Jest набор тестов определяется с помощью функции describe
, которая принимает два аргумента: строку, описывающую набор, и функцию обратного вызова, которая содержит один или несколько тестовых случаев с использованием функций test
или it
. Функция describe
позволяет группировать связанные тесты в один набор. Например:
describe('calculator', () => { test('addition', () => { expect(1+1).toBe(2); }); test('subtract', () => { expect(5-3).toBe(2); }); });
Организация тестов в наборы позволяет группировать связанные тесты вместе, что облегчает понимание цели и области действия каждого тестового файла. Это также помогает поддерживать организованность и удобство сопровождения тестового кода, особенно по мере роста кодовой базы. Кроме того, наборы тестов могут предоставлять более детализированную информацию о выполняемых тестах, что делает отчет о тестировании более удобочитаемым и ценным.
В этом руководстве для тестирования приложения React нам понадобится React-Testing-Library. Библиотека тестирования React — это легкая библиотека для тестирования компонентов React. Он предоставляет набор утилит, которые позволяют разработчикам писать тесты, имитирующие поведение пользователя, и подтверждающие, что их компоненты правильно отображаются на основе этого поведения. Библиотека фокусируется на тестировании поведения компонентов, а не деталей их реализации, что делает тесты более устойчивыми к изменениям в реализации компонента.
Кроме того, библиотека поощряет разработчиков к написанию тестов, которые очень похожи на то, как пользователи взаимодействуют с компонентом. Это может помочь отловить ошибки, которые не могут быть обнаружены тестами, сосредоточенными только на деталях реализации.
Написание базового теста
Нашим самым первым тестом будет простой render
. Этот тест использует функцию render
из @testing-library/react
для рендеринга компонента AComponent
и ожидает, что он будет рендериться без ошибок:
import React from 'react'; import { render } from '@testing-library/react'; import AComponent from './AComponent.tsx'; test('renders AComponent without errors', () => { render(<AComponent />); });
Тесты компонентов React также должны проверять правильность поведения компонента в ответ на взаимодействие с пользователем, реквизиты и изменения состояния.
Например:
import React from 'react'; import { render, fireEvent, screen } from '@testing-library/react'; import AComponent from './AComponent'; test('updates state when button is clicked', () => { const { getByText } = render(<AComponent />); const button = screen.getByText('Click me'); fireEvent.click(button); expect(button).toHaveTextContent('Clicked!'); });
Этот тест использует функцию fireEvent
из @testing-library/react
для имитации нажатия кнопки и ожидает, что кнопка обновит свое текстовое содержимое на «Нажато!»
Примечание. Хотя метод fireEvent, предоставляемый библиотекой тестирования React, может имитировать взаимодействие с пользователем, часто более реалистично использовать библиотеку userEvent. `userEvent` обеспечивает более точную симуляцию того, как пользователь будет взаимодействовать с вашими компонентами, и может помочь выявить ошибки, которые невозможно обнаружить с помощью более абстрактного метода fireEvent.
Используйте userEvent
для реалистичного действия
userEvent обеспечивает более точное моделирование того, как пользователи взаимодействуют с вашими компонентами.
import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import Button from "./Button"; test("clicking a button", () => { render(<Button />); const button = screen.getByRole("button"); userEvent.click(button); expect(button).toHaveTextContent("Clicked"); });
Тесты компонентов React также должны проверять правильность рендеринга компонента с разными значениями реквизита. Вот пример теста для компонента, который отображает список элементов на основе свойств:
import React from 'react'; import { render, screen } from '@testing-library/react'; import AComponent from './AComponent'; test('renders list of items correctly', () => { const items = [ { id: 1, text: 'Item 1' }, { id: 2, text: 'Item 2' }, { id: 3, text: 'Item 3' }, ]; const { getAllByTestId } = render(<AComponent items={items} />); const itemsList = screen.getAllByTestId('item'); expect(itemsList).toHaveLength(items.length); itemsList.forEach((item, index) => { expect(item).toHaveTextContent(items[index].text); }); });
Этот тест передает массив реквизитов items
компоненту AComponent
и ожидает, что он отобразит список элементов с правильным текстовым содержимым и длиной.
Насмешки и заглушки
В некоторых случаях может потребоваться изолировать зависимости, чтобы облегчить тестирование сложного кода. Насмешки и заглушки — это методы создания поддельных объектов или функций, имитирующих поведение реальных зависимостей.
Макеты — это поддельные объекты с предопределенным поведением, которые можно использовать для замены реальных объектов в тестах. Заглушки — это поддельные функции, которые заменяют настоящие функции в тестах и возвращают заранее определенные значения. У Мартина Фаулера есть старая, более содержательная статья о моках и заглушках и некоторых практиках тестирования. Почитайте, если еще не читали.
Вот пример использования макета для изоляции зависимости в тесте:
import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from "@testing-library/user-event"; import axios from 'axios'; import AComponent from './AComponent'; jest.mock('axios'); test('fetches data and updates state', async () => { const data = { id: 1, name: 'John' }; axios.get.mockResolvedValue({ data }); const { getByText } = render(<AComponent />); const button = screen.getByText('Fetch data'); userEvent.click(button); const dataElement = screen.getByText(data.name); expect(dataElement).toBeInTheDocument(); });
Этот тест использует функцию jest.mock
для создания имитации зависимости axios
и использует функцию mockResolvedValue
для определения ее поведения. Затем тест имитирует щелчок кнопки в компоненте AComponent
, который запускает вызов зависимости axios
с фиктивным поведением.
Отчет о тестировании
Вы также можете создать тестовый отчет, чтобы увидеть статистические данные и провести некоторый анализ того, как покрытие меняется с течением времени. Это отличный способ поделиться этими данными в среде непрерывной интеграции, чтобы все в команде могли это четко видеть.
Во-первых, установите пакет jest-html-reporters
в корень вашего проекта. А затем в package.json
добавить еще одну команду report
в раздел скриптов. И каждый раз, когда вы запускаете npm run report
, он будет генерировать для вас отчет.
"report": "react-scripts test --env=jsdom --reporters=default \ --reporters=jest-html-reporters"
Краткое содержание
В заключение, тестирование является неотъемлемой частью разработки программного обеспечения и имеет решающее значение для обеспечения надежности и высокого качества кодовой базы. Jest и React-Testing-Library — отличные инструменты для тестирования приложений React, и с их помощью разработчики могут выявлять ошибки на ранней стадии, снижать затраты на устранение проблем и быть уверенными в качестве своего кода.
Кроме того, при правильной настройке и отчетности разработчики могут легко отслеживать состояние своей кодовой базы и выявлять области, требующие улучшения. Включив тестирование в свой процесс разработки, разработчики могут создавать более качественные приложения React и обеспечивать лучший пользовательский интерфейс.
Если вам понравилось чтение, пожалуйста, Подпишитесь на мою рассылку. Я еженедельно делюсь методами чистого кода и рефакторинга в блогах, книгах и видео.