[Ruby on Rails 3, Ruby on Rails 4] RSpec/Capybara: Spork でテストを高速化する
つづき。
「Ruby on Rails チュートリアル」をさわってみます。
テストが開始されるまで時間がかかるのは、Railsの環境全体を読み込み直す必要があるから。
Spork は、これを解決することでテストの速度を向上させるとのこと。
Contents
Gemfile
group :development, :test do
gem 'sqlite3', '~> 1.3.5'
gem 'rspec-rails', '~> 2.11.0'
gem 'guard-rspec'
gem 'guard-spork'
gem 'childprocess'
gem 'spork'
end
インストール
% bundle install
% bundle exec spork --bootstrap
Using RSpec
Bootstrapping /Users/****/projects/sample_app/spec/spec_helper.rb.
Done. Edit /Users/****/projects/sample_app/spec/spec_helper.rb now with your favorite text editor and follow the instructions.
spec/spec_helper.rb
指示された spec/spec_helper.rb を設定します。
% subl spec/spec_helper.rb
ファイルを確認すると、Spork によって、2つのメソッドが追加されていました。
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
さらにファイルの中程から最後をみると、rspecの記述があるのでこれをコメントアウトして、Spork.prefork 内にコピーしてみました。
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
config.order = "random"
end
end
Spork を起動する
以下でサーバが起動します。
% bundle exec spork
Using RSpec
Preloading Rails environment
Loading Spork.prefork block...
Spork is ready and listening on 8989!
速度の比較
–drb (“distributed Ruby” の略) オプションを追加することで、Spoke が利用されるので、速度を比較してみる。
% time bundle exec rspec spec/requests/static_pages_spec.rb
........
Finished in 0.35374 seconds
8 examples, 0 failures
Randomized with seed 44534
bundle exec rspec spec/requests/static_pages_spec.rb 3.24s user 0.74s system 97% cpu 4.085 total
% time bundle exec rspec spec/requests/static_pages_spec.rb --drb
........
Finished in 0.38702 seconds
8 examples, 0 failures
Randomized with seed 48212
bundle exec rspec spec/requests/static_pages_spec.rb --drb 0.86s user 0.14s system 63% cpu 1.579 total
CPU使用率が違うようですが、半分以下になっているようです。
.rspec
Spork を標準で使えるよう、RSpecの設定に追加する。
% subl .rspec
--color
--drb
GuardにSporkを導入する
GuardfileにSporkを追加します。
% bundle exec guard init spork
23:37:33 - INFO - spork guard added to Guardfile, feel free to edit it
% subl Guardfile
追加された以下のセクションを、RSpecセクションの上に移動します。
guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
watch('config/application.rb')
watch('config/environment.rb')
watch('config/environments/test.rb')
watch(%r{^config/initializers/.+\.rb$})
watch('Gemfile.lock')
watch('spec/spec_helper.rb') { :rspec }
watch('test/test_helper.rb') { :test_unit }
watch(%r{features/support/}) { :cucumber }
end
さらにRSpecセクションに、, :cli => '--drb'
を追加します。
guard 'rspec', :version => 2, :all_after_pass => false, :cli => '--drb' do
GuardとSporkを同時に起動する
guardコマンドでGuardとSporkを同時に起動します。
% bundle exec guard
23:49:58 - INFO - DEPRECATION WARNING: The :version option is deprecated. Only RSpec 2 is now supported.
23:49:58 - INFO - Guard is using TerminalNotifier to send notifications.
23:49:58 - INFO - Guard is using TerminalTitle to send notifications.
23:49:59 - INFO - Starting Spork for RSpec
Using RSpec
Preloading Rails environment
Loading Spork.prefork block...
Spork is ready and listening on 8989!
23:50:05 - INFO - Spork server for RSpec successfully started
23:50:05 - INFO - Guard::RSpec is running
23:50:05 - INFO - Running all specs
Running tests with args ["--drb", "-f", "progress", "-r", "/Users/****/projects/sample_app/vendor/bundle/ruby/2.0.0/gems/guard-rspec-2.5.4/lib/guard/rspec/formatter.rb", "-f", "Guard::RSpec::Formatter", "--failure-exit-code", "2", "spec"]...
........
Finished in 0.41932 seconds
8 examples, 0 failures
Randomized with seed 28763
Done.
23:50:08 - INFO - Guard is now watching at '/Users/****/projects/sample_app'
[1] guard(main)>
補遺
preforkで読み込むファイル (たとえばroutes.rb) が変更された場合、Sporkサーバーを再起動して新しいRailsの環境を再度読み込む必要があります。パスするはずのテストが失敗した場合は、Ctrl-CでSporkサーバーを停止して再起動してください。
Spoke の設定
- ASCIIcasts – “Episode 285 – Spork”
例えば FactoryGirl でひつようなもの。
Spork.each_run do
FactoryGirl.reload
end