Pull to refresh

Combustion — альтернативный подход к тестированию Rails Engines

Reading time 4 min
Views 1.5K
Original author: Pat Allan
Сегодня мы предоставим вашему вниманию перевод поста Пета Аллана (Pat Allan), известного разработчика, приверженца Ruby, одного из победителей Ruby Hero Award 2009 года. Что это за награда? Она присуждается победителями прошлого года тем участникам сообщества, которые наиболее проявили себя: создали значимый обучающий контент, разработали плагины и гемы, участвовали в проектах с открытым кодом. Такая награда была создана для того, чтобы отметить наиболее проявивших себя людей и дать им признание, которое они заслуживают.

Пообщаться со Петом можно будет на конференции RubyC в Киеве 5-6 ноября этого года.


Значительную часть прошлого месяца я провел за написанием моего первого Rails engine — тем не менее я не закончил, да и сама работа была для клиента, так, что на деталях останавливаться я не могу.

В процессе разработки довольно быстро стало ясно, что необходим способ тестировать Rails engine. Не беря во внимание простейшие unit-тесты, довольно привычная практика для интеграционного тестирования — хранить копию приложения на рельсах внутри директории spec или test.

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

Целью было организовать всестороннее тестирование в простом и понятном виде: написание тестов внутри моей собственной spec директории, а не упаковка их в директорию spec, рядом с Rails-приложением, над которым проводится тестирование. Кроме того, было бы не плохо воспользоваться Capybara DSL.

Конечно, необходимо было настоящее приложение на Rails, на базе которого проводилось бы тестирование, но, как выяснилось, от большей части файлов приложения, генерируемого рельсами, можно избавиться. И действительно — единственный файл, который необходим Rails, это config/database.yml — и то только в том случае, если вам нужно использовать ActiveRecord.

Добро пожаловать в Combustion — мое минимальное приложение-библиотека для тестирования engines, со всеми значениями по умолчанию, взятыми для типичного приложения на Rails.

Настраиваемся

Типичная настройка/установка выглядит следующим образом:
  • добавте гем в ваш Gemfile (и выполните команду bundle — прим. пер.);
  • запустите генератор в директории вашего Rails engine для того чтобы создать заглушку приложения Rails: combust (или bundle exec combust, если в гемфайле вы используете репозиторий гит);
  • добавте Combustion.initialize! в spec/spec_helper.rb (пока поддерживается только RSpec, но если нужно для TestUnit — проблем с патчем возникнуть не должно).
Вот типичный spec_helper.rb, учитывая Capybara:
require 'rubygems'
require 'bundler'

Bundler.require :default, :development

require 'capybara/rspec'

Combustion.initialize!

require 'rspec/rails'
require 'capybara/rails'

RSpec.configure do |config|
  config.use_transactional_fixtures = true
end

Заставляем всё работать

Прежде всего, вам нужно убедиться, что вы используете Rails engine внутри приложения Rails. Генератор должен был добавить нужные хуки, которые нам как-раз для этого понадобятся. Если вам нужно добавить роуты, отредактируйте spec/internal/config/routes.rb. Если вам нужны модели, убедитесь, что добавили их в spec/internal/db/schema.rb. Чуть более детально всё описано в README.

Всё, самое время приступить к написанию тестов! Вот небольшой пример:
# spec/controllers/users_controller_spec.rb
require 'spec_helper'

describe UsersController do
  describe '#new' do
    it "runs successfully" do
      get :new

      response.should be_success
    end
  end
end

Или используя Capybara для интеграционного теста:
# spec/acceptance/visitors_can_sign_up_spec.rb
require 'spec_helper'

describe 'authentication process' do
  it 'allows a visitor to sign up' do
    visit '/'

    click_link 'Sign Up'
    fill_in 'Name',     :with => 'Pat Allan'
    fill_in 'Email',    :with => 'pat@no-spam-please.com'
    fill_in 'Password', :with => 'chunkybacon'
    click_button 'Sign Up'

    page.should have_content('Sign Out')
  end
end

Поворачиваем ключ

Ах да, а вот и один из моих самых любимых хелперов: генератор Combustion добавляет файл config.ru к вашему engine, что означает следующее: вы можете запустить ваше тестовое приложение в браузере — достаточно запустить rackup и перейти по адресу localhost:9292.

Некоторые оговорки

Как уже было сказано, Combustion создан для RSpec, но я с радостью приму патчи для TestUnit. Это же касается и Cucumber'а — в теории должно работать, но я не проверял.

Кроме того, гем написан для Rails 3.1 — он должен работать с Rails 3.0 после нескольких патчей, но я сильно сомневаюсь, что заработает с чем-то до 3.0. Тем не менее, не стесняйтесь исследовать.

Так же есть вероятность, что для гем пригодится для интеграционного тестирования библиотек, которые не являются engine'ами. Если вы захотите это проверить — я с радостью поинтересуюсь как продвигается процесс.

Заключение

Что ж, давайте посмотрим куда нас занесло.
  • вы можете тестировать ваши engines на минимально необходимом приложении Rails;
  • в ваше Rails приложение вы добавляете только то, что нужно для тестирования;
  • ваш тестировый код гораздо чище (привет, DRY!) и его проще поддерживать;
  • вы можете использовать стандатные хелперы им. RSpec и Capybara для интеграционного тестирования;
  • благодаря Rack, вы можете вживую просматривать ваше тестовое приложение.
Я не первый кому пришла подобная идея — после того как я окончил работу над Combustion, мне указали на тестовую оболочку для Kaminari, которая выполняет ту же функцию (просто она не была вынесена в отдельную библиотеку). Я не удивлюсь, если кто-то другой сделал то же самое — но когда я искал похожие, постоянно натыкался на известные библиотеки, которые шли вместе с полным приложением на рельсах внутри их директорий test или spec.

Если вам кажется что Combustion может украсить ваш engine, пробуйте — поиск ошибок и прибавление уверенности в том что гем работает на более широком спектре задач только приветствуется. Патчи и отзывы приветствуются однозначно.
Tags:
Hubs:
+15
Comments 3
Comments Comments 3

Articles