Ruby On Rails
Теория: Качество
Некачественный код может привести к множеству проблем, включая трудности в сопровождении, увеличение времени на исправление ошибок и снижение производительности приложения. Инструменты для обеспечения качества кода позволяют выявлять ошибки и проверять соответствие стандартам. К таким инструментам относятся линтеры, статические анализаторы и тесты.
В этом уроке мы рассмотрим статический анализатор кода и линтер RuboCop. Мы изучим его установку, настройку и использование для анализа кода, а также познакомимся с основами тестирования в Rails, что поможет обеспечить надежность и стабильность разрабатываемых приложений.
Статический анализатор RuboCop
RuboCop — это статический анализатор кода для Ruby, который помогает поддерживать стиль кода и следовать соглашениям в проекте. Он основан на Ruby Style Guide и предоставляет правила (копов), которые можно настраивать в зависимости от потребностей проекта. Основные возможности RuboCop включают:
- Статический анализ: Проверка кода на соответствие стилю и стандартам.
- Автоматическая корректировка: Возможность автоматически исправлять некоторые недочеты.
- Настраиваемые правила: Возможность включать или отключать определенные правила в зависимости от требований проекта.
- Интеграция с редакторами: Поддержка плагинов для популярных редакторов, что позволяет получать обратную связь в реальном времени.
Установка RuboCop
Чтобы установить RuboCop для Rails, нужно добавить его в Gemfile:
Так как в это dev-зависимость, то и добавляется Rucobop в окружение для разработки и для тест-окружения (для CI).
Дальше необходимо установить новую зависимость с помощью Bundler:
Проверим, что RuboCop установлен:
Файл конфигурации
RuboCop по умолчанию поставляется со своими правилами и проверяет весь проект. Чтобы применить тонкую настройку, мы можем создать файл .rubocop.yml и добавить туда правила проверок:
Ранее вместе с RuboCop мы добавили гемы rubocop-rails и rubocop-performance - это наборы правил для Rails-приложений. Чтобы их включить нужно их добавить в .rubocop.yml:
Обычно файлы конфигурации не пишут с нуля, а используют готовые, из проекта-шаблона или из предыдущего проекта. Например в проекте Hexlet CV мы можем взять конфиг и добавить к себе.
RuboCop установлен и настроен, теперь необходимо проверить проект на ошибки и соответствие стайл гайду.
Проверка кода
Если мы запустим RuboCop первый раз, мы увидим множество ошибок. Точное их количество будет в конце
Вывод команды bundle exec rubocop показывает, что было проверено 33 файла, и обнаружено 166 недочетов (offenses). Все недочеты помечены буквой "C", что указывает на то, что они являются проблемами стиля (Correctable) и их можно исправить автоматически.
RuboCop предоставляет возможность автоматической корректировки кода. Для этого используются две основные опции:
- Опция
-aисправляет только те недочеты, которые не могут повредить бизнес-логике (например, форматирование кода). - Опция
-Aможет вносить изменения, которые потенциально могут повлиять на логику приложения. Но ее можно использовать без опасений на новом проекте, в котором еще нет никакой логики.
Вывод команды похож на тот, что вы получили при проверке, только здесь будут отмечены применённые исправления. Не все исправления можно выполнить автоматически, поэтому внимательно изучите отчет анализатора.
Тестирование
Rails предоставляет мощные инструменты для написания и выполнения тестов. Тесты обычно располагаются в директории test/, где они разделены по директориям:
- test/models/ — для тестов моделей.
- test/controllers/ — для тестов контроллеров.
- test/integration/ — для интеграционных тестов.
- test/system/ — для системных тестов.
Для большинства Rails-приложений тестов для контроллеров уже достаточно, чтобы обеспечить базовую проверку приложения. Однако в зависимости от сложности приложения и требований к качеству, может потребоваться также использование других типов тестов, таких как системные тесты.
Пример тестов контроллера резюме в Hexlet CV:
В этих тестах используется фреймворк тестирования Minitest с гемом power-assert.
Фикстуры
Фикстуры в Rails — это способ предварительной загрузки данных в базу данных для тестирования. Они позволяют создавать наборы данных, которые могут быть использованы в тестах, чтобы обеспечить предсказуемую и стабильную среду для выполнения тестов. Фикстуры особенно полезны там, где необходимо иметь определенные данные для проверки работы приложения.
Фикстуры обычно хранятся в формате YAML. Каждый файл фикстуры соответствует одной модели и содержит записи, которые будут загружены в базу данных перед выполнением тестов. В файле фикстуры каждая запись имеет уникальный идентификатор, который используется для ссылки на эту запись в тестах.
Фикстуры автоматически загружаются в базу данных перед выполнением тестов. Это происходит благодаря методу fixtures() в тестах, который указывает, какие фикстуры нужно загрузить.
В тестах можно обращаться к загруженным фикстурам по их идентификаторам:
Фикстуры позволяют легко создавать и управлять тестовыми данными. Особенно там, где требуется сложное состояние БД. Они обеспечивают консистентность данных между тестами. Фикстуры можно использовать с гемами faker или factory_bot_rails для того, чтобы упростить создание фикстур там, где не нужны конкретные значения.
Транзакционные тесты
Транзакционные тесты в Rails — это подход к тестированию, при котором каждый тест выполняется в рамках транзакции базы данных. Это позволяет изолировать тесты друг от друга и гарантировать, что изменения, внесенные в базу данных в ходе теста, не повлияют на другие тесты. После завершения теста транзакция откатывается, и база данных возвращается в исходное состояние.
Каждый тест выполняется в своей транзакции, что предотвращает "загрязнение" базы данных. Это особенно полезно, когда тесты изменяют данные, так как изменения не сохраняются после завершения теста. В Rails при использовании ActiveSupport::TestCase транзакционные тесты включены по умолчанию.
Пример транзакционного теста:
Пишем первый тест
Когда мы вызываем генератор для создания контроллера, то создается также класс для тестирования этого контроллера. Вызовем генератор для создания контроллера:
Получили пустой контроллер:
И тестовый класс без методов
Добавим обработчик в config/routes.rb
И добавим тест на добавленный роут
В контроллер добавим экшен:
И шаблон app/views/pages/index.html.erb, который будет выводиться экшеном:
Теперь мы готовы запустить тесты и проверить, что все работает. Запустить тесты можно командой bin/rails test:
Запуск тестов завершился успешно. Если на каком-то из этапов возникла бы ошибка, то тесты бы об этом сообщили. Например так выглядит ошибка, если нет экшена и шаблона:
binding.irb
В Ruby и Rails есть инструмент для отладки кода - binding.irb, который позволяет вам вставлять интерактивную консоль в любое место вашего кода. Это может быть особенно полезно для диагностики проблем, анализа состояния переменных и выполнения произвольного кода в контексте текущего выполнения программы.
Чтобы использовать irb, нужно вызвать binding.irb внутри кода:
Использовать binding.irb можно даже во время выполнения тестов
Заключение
В ходе урока мы познакомились с RuboCop — статическим анализатором кода для Ruby, который помогает поддерживать стиль и стандарты кода в проектах. Мы рассмотрели процесс установки и настройки RuboCop, включая создание конфигурационного файла .rubocop.yml для настройки правил проверки. Также мы изучили, как использовать RuboCop для анализа кода и автоматической корректировки недочетов.
Мы обсудили основы тестирования в Rails, включая использование фикстур и транзакционных тестов, а также написание простых тестов для контроллеров.
Рассмотрели инструмент binding.irb для отладки кода, который позволяет отлаживать и исправлять ошибки в приложении.

