Spork DRb, RSpec и Rails 3.2

февраля 17, 2012  |  Published in BDD, Development Processes, RSpec, Тестирование  |  9 Comments

Когда вы запускаете тесты для вашего приложения, то сами тесты выполняются достаточно быстро, а значительное время забирает запуск вашего приложения на Rails для тестирования. Каждый раз выполняя тесты все заново запускаете свое приложение.

Для решения этой проблемы было предложено решение, которое называется Spork. Spork является DRb сервисом (сервером), суть которого заключается в том, что он держит приложение постоянно загруженным, так что вам не нужно его запускать каждый раз вместе с запуском тестов.

В данной статье мы рассмотрим работу Spork совместно с RSpec для Rails 3.2. Мы будем использовать RSpec потому, что он имеет встроенную поддержку DRb сервисов и является одним из самых популярных решений для тестирования и написания спецификаций.

Установка Spork происходит как и установка любого другого gem для Rails — через добавление его в Gemfile:

group :test do
  gem "rspec"
  gem "spork"
end

$ bundle install

После установки Spork необходимо выполнить следующую команду:

$ spork — -bootstrap

Благоаря которому Spork запишет себя в файл  spec/spec_helper.rb, вот что конкретно будет добавлено:

require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'

Spork.prefork do
  # Loading more in this block will cause your tests to run faster. However,
  # if you change any configuration or code from libraries loaded here, you'll
  # need to restart spork for it take effect.

end

Spork.each_run do
  # This code will be run each time you run your specs.

end

В блоке передаваемом в метод Spork.prefork мы должны указывать те файлы, которые не изменяются ибо при изменении этих файлов вам будет необходимо перезапускать Spork для того, чтобы была загружена обновленная версия вашего приложения на Rails. Все, что вы не указали в этом блоке будет постоянно перезагружаться.

В блоке передаваемом в метод Spork.each_run помещается код, который должен выполняться при каждом запуске тестов.

После небольшого редактирования ваш файл spec_helper.rb должен выглядеть примерно так:

require 'rubygems'
require 'spork'

Spork.prefork do
  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  require 'rspec/autorun'

  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

  RSpec.configure do |config|
    #config.fixture_path = "#{::Rails.root}/spec/fixtures"
    #config.use_transactional_fixtures = true
    config.infer_base_class_for_anonymous_controllers = false
  end
end

Spork.each_run do
  #Подгружаем каждый раз все файлы из директории app/
  Dir["#{Rails.root}/app/**/*.rb"].each {|file| load file }
  #Подгружаем файл с описанием маршрутизации
  load "#{Rails.root}/config/routes.rb"
end

При запуске Spork мы настраиваем RSpec, а при каждом запуске тестов мы обновляем в оперативной памяти все файлы загруженные из директории app (контроллеры, модели, вьюхи, хэлперы и т.д.) и файл описания маршрутизации. Прежде чем приступить к тестированию не забудьте отключить кэширование классов в файле config/environments/test.rb:

config.cache_classes = false

Для запуска Spork (сервера) вам необходимо просто выполнить следующую команду:

$ spork
Using RSpec
Preloading Rails environment
Loading Spork.prefork block…
Spork is ready and listening on 8989!

Далее для выполнения тестов выполняем команду rspec с флагом —drb (два знака минус, а не тире), чтобы RSpec использовал ранее запущенное Spork’ом приложение, а не запускал его самостоятельно:

$ rspec spec/ —drb
***

Pending:
  Article add some examples to (or delete) /home/vladimir/projects/quasar/spec/models/article_spec.rb
    # No reason given
    # ./spec/models/article_spec.rb:4
  Admin::ArticlesHelper add some examples to (or delete) /home/vladimir/projects/quasar/spec/helpers/admin/articles_helper_spec.rb
    # No reason given
    # ./spec/helpers/admin/articles_helper_spec.rb:14
  Admin::DashboardHelper add some examples to (or delete) /home/vladimir/projects/quasar/spec/helpers/admin/dashboard_helper_spec.rb
    # No reason given
    # ./spec/helpers/admin/dashboard_helper_spec.rb:14

Finished in 0.06046 seconds
3 examples, 0 failures, 3 pending

Тесты сработали мгновенно, спасибо Spork’у, а точнее его авторам!

Ссылки

Tags: , , ,

Responses

  1. poslannik iz nebes says:

    февраля 17, 2012 at 22:52 (#)

    Отлично! Надо будет на работе потестить. Надеюсь теперь не придётся по 30 — 60 секунд ждать выполнения тестов.
    Было бы, кстати, интересно увидеть сравнение без спорка и со спорком.

  2. says:

    февраля 17, 2012 at 23:33 (#)

    Думаю, что для ускорения тестов все же был создан Spork, а DRb (модуль из stdlib в ruby) написали задолго до этого — и, возможно, с совершенно другими целями.

  3. admin says:

    февраля 18, 2012 at 13:14 (#)

    7even, спасибо за замечание, написал глупость, чуть позже исправлю.

  4. admin says:

    февраля 21, 2012 at 11:39 (#)

    Поправил статью согласно комментарию 7even.

  5. ip82 says:

    марта 16, 2012 at 12:22 (#)

    В spec_helper.rb надо бы еще очистку тестовой базы с помощью database_cleaner запихнуть, это практически всегда требуется)

  6. says:

    июля 22, 2012 at 12:52 (#)

    А как spork дружит с Gem’ами? Узнает ли он, добавил я новый в gemfile?

  7. admin says:

    июля 22, 2012 at 13:02 (#)

    Виктор, за этим guard следит.

  8. Oleg says:

    апреля 6, 2013 at 20:11 (#)

    Добрый день. Не подскажите куда копать? выполняю на Linux Mint, следуя инструкциям здесь (настройки в точности как и там), запускаю spork и в другом терминале пытаюсь запустить тест. guard без bundle exec не запускается, а когда с ним запускаю, то выдает — «Could not find rake-10.0.4 in any of the sources». Без запущенного spork все работает..

  9. Oleg says:

    апреля 7, 2013 at 08:21 (#)

    Помогло это — ttp://stackoverflow.com/questions/5782684/rails-commands-only-work-on-one-terminal

Leave a Response

Для подсветки кода используйте BB - коды: [language]...[/language], где language может быть: ruby, javascript, css, html.