Git hooks и pre-commit тесты

Git hooks — это скрипты, которые могут быть выполнены автоматически в определённые моменты жизненного цикла работы с Git-репозиторием. Они позволяют автоматизировать выполнение задач на различных этапах работы с репозиторием, например, при коммите, пуше или при получении обновлений. Git hooks — мощный инструмент для интеграции различных тестов, линтинга и других процессов в рабочий процесс разработчика.

Одним из популярных применений Git hooks является автоматизация тестирования перед коммитом с помощью pre-commit hook. Использование такого подхода позволяет обеспечивать качество кода ещё до того, как изменения попадут в репозиторий. В случае с тестированием React-приложений, можно настроить pre-commit hook таким образом, чтобы перед каждым коммитом выполнялись юнит-тесты, а также тесты компонентов с использованием React Testing Library. Это позволит избежать попадания в репозиторий неподготовленного или ошибочного кода.

Настройка pre-commit hook

Для того чтобы настроить pre-commit hook для запуска тестов, первым делом потребуется установить несколько зависимостей:

  1. Prettier, ESLint, Jest — для тестирования и линтинга.
  2. Husky — для работы с Git hooks.
  3. lint-staged — для того чтобы запускать линтер и тесты только на изменённых файлах.

Для начала нужно установить все необходимые зависимости:

npm install husky lint-staged --save-dev

После этого можно инициализировать Husky:

npx husky install

Теперь можно добавить настройку для pre-commit hook. Для этого нужно создать в проекте файл .husky/pre-commit и добавить в него команды для запуска тестов. Это можно сделать так:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# Запуск тестов только для изменённых файлов
npx lint-staged

Также нужно настроить, что именно будет выполняться с изменёнными файлами. Для этого в package.json добавляется следующая конфигурация:

{
  "lint-staged": {
    "*.js": [
      "eslint --fix",
      "jest --bail --findRelatedTests"
    ]
  }
}

В этом примере для всех изменённых JavaScript-файлов будут автоматически запускаться два процесса:

  1. ESLint для проверки и исправления ошибок в коде.
  2. Jest для запуска тестов, относящихся к изменённым файлам.

Запуск тестов с помощью Jest

Jest — это популярный фреймворк для тестирования JavaScript и React-приложений, который легко интегрируется с React Testing Library. Настройка тестов с Jest обычно включает в себя следующие шаги:

  1. Установить необходимые пакеты:

    npm install --save-dev jest @testing-library/react @testing-library/jest-dom
  2. Создать конфигурацию Jest в package.json или в отдельном файле jest.config.js. Для базовой настройки достаточно указать несколько параметров:

    {
      "testEnvironment": "jsdom",
      "transform": {
        "^.+\\.jsx?$": "babel-jest"
      }
    }
  3. Написать тесты с использованием React Testing Library. Пример теста для компонента:

    import { render, screen } from '@testing-library/react';
    import MyComponent from './MyComponent';
    
    test('рендерит компонент с текстом', () => {
      render(<MyComponent />);
      const linkElement = screen.getByText(/Hello, world!/i);
      expect(linkElement).toBeInTheDocument();
    });

Интеграция pre-commit hook с Jest

После того как настройка pre-commit hook и тестов завершена, важно убедиться, что тесты запускаются только для тех файлов, которые были изменены в коммите. Это достигается с помощью lint-staged. Команды, приведённые ранее, гарантируют, что перед каждым коммитом будут выполнены следующие шаги:

  1. Проверка линтом с исправлением ошибок (если это возможно).
  2. Запуск тестов только для тех файлов, которые были изменены, с использованием флага --findRelatedTests.

Такой подход существенно ускоряет процесс тестирования, поскольку тесты запускаются только для изменённых файлов, а не для всего проекта.

Преимущества использования Git hooks и pre-commit тестов

  1. Автоматизация качества кода: Каждый коммит будет проверяться на ошибки линтинга и не проходить, если тесты не пройдены.
  2. Повышение уверенности в коде: Тесты выполняются автоматически, что позволяет исключить ошибки, которые могли бы быть пропущены при обычной ручной проверке.
  3. Снижение времени на проверку: Поскольку тесты запускаются только для изменённых файлов, процесс проверки занимает меньше времени.
  4. Снижение риска нарушения целостности кода: Код не попадёт в репозиторий, если он не прошёл все тесты и линтинг, что помогает поддерживать качество и стабильность проекта.

Расширение функциональности

По мере роста проекта может возникнуть необходимость в дополнительной настройке или расширении возможностей pre-commit hook. Например, можно добавить:

  • Запуск тестов для всех файлов в проекте (не только для изменённых).
  • Добавление дополнительных этапов тестирования (например, интеграционные тесты или тесты на производительность).
  • Интеграция с другими инструментами — такими как кодовые покрытия (например, с помощью jest --coverage) или проверка типов (например, с помощью TypeScript или Flow).

Заключение

Использование Git hooks, а именно pre-commit hook, для автоматизации тестирования с использованием Jest и React Testing Library является важным шагом для обеспечения качества кода. Этот подход помогает поддерживать высокие стандарты в проекте, ускоряет процесс разработки и предотвращает попадание ошибочного кода в репозиторий.