Question

I am developing a Rails project via a Vagrant box (Ubuntu 32-bit, Rails 4.0.3, Ruby 2.1.0p0).

I've just tried adding Spork to my project to speed up my tests (using RSpec, Capybara), and am seeing significantly slower tests. If I run simply "rspec .", all my tests pass in 5.83 seconds. However, when I run guard via "guard -c -p", I save one of my spec files, and I get a time of 26.08 seconds.

Note: I have to run "guard -p" to actually get guard to run my tests on file save through Vagrant.

When guard starts running the tests, it shows the args:

["--color", "--failure-exit-code", "2", "--format", "progress", "--format",   
"Guard::RSpec::Formatter", "--require", "/home/vagrant/.rvm/gems/ruby-2.1.0/  
gems/guard-rspec-4.2.7/lib/guard/rspec/formatter.rb", "spec"]...

I see that "--format" is listed twice, and "--drb" is not showing up at all.

Here's my Guardfile:

guard 'spork', :rspec_env => { 'RAILS_ENV' => 'test' }, :test_unit => false 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 }
end

guard :rspec, :cmd => 'rspec --drb' do
  watch(%r{^spec/.+_spec\.rb$})
  watch(%r{^lib/(.+)\.rb$})     { |m| "spec/lib/#{m[1]}_spec.rb" }
  watch('spec/spec_helper.rb')  { "spec" }

  # Rails example
  watch(%r{^app/(.+)\.rb$})                           { |m| "spec/#{m[1]}_spec.rb" }
  watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$})          { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
  watch(%r{^app/controllers/(.+)_(controller)\.rb$})  { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
  watch(%r{^spec/support/(.+)\.rb$})                  { "spec" }
  watch('config/routes.rb')                           { "spec/routing" }
  watch('app/controllers/application_controller.rb')  { "spec/controllers" }
end


guard 'livereload' do
  watch(%r{app/views/.+\.(erb|haml|slim)$})
  watch(%r{app/helpers/.+\.rb})
  watch(%r{public/.+\.(css|js|html)})
  watch(%r{config/locales/.+\.yml})
  # Rails Assets Pipeline
  watch(%r{(app|vendor)(/assets/\w+/(.+\.(css|js|html|png|jpg))).*}) { |m| "/assets/#{m[3]}" }
end

Here is my spec_helper.rb:

require 'rubygems'
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.

  # This file is copied to spec/ when you run 'rails generate rspec:install'
  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  require 'rspec/autorun'
  require 'capybara/rspec'

  # Requires supporting ruby files with custom matchers and macros, etc,
  # in spec/support/ and its subdirectories.
  Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

  # Checks for pending migrations before tests are run.
  # If you are not using ActiveRecord, you can remove this line.
  ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)

  RSpec.configure do |config|

    config.use_transactional_fixtures = true
    config.infer_base_class_for_anonymous_controllers = false
    config.order = "random"

    #Devise
    config.include Devise::TestHelpers, type: :controller

    #Capybara
    config.include Capybara::DSL
  end

end

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

end

The only thing in my .rspec :

--color

The relevant part of my Gemfile:

group :development, :test do
  gem 'rspec-rails', '~> 2.0'
  gem 'factory_girl_rails'
  gem 'guard-rspec'
  gem 'guard-livereload'
  gem 'spork-rails'
  gem 'guard-spork'
end

group :test do
  gem 'shoulda-matchers'
  gem 'capybara'
end

I've noticed that if I have guard running, then save a file, at times I will get an error:

Could not start Spork server for rspec after 30 seconds. I will continue  
waiting for a further 60 seconds.

I'm not sure why it's taking so long after installing Spork, especially when rspec is much faster going through the same Vagrant box. Any ideas?

Was it helpful?

Solution

There's a new --listen-on option since Guard 2.5: https://github.com/guard/guard/releases/tag/v2.5.0

From Guard's README:

Use Listen's network functionality to receive file change events from the network. This is most useful for virtual machines (e.g. Vagrant) which have problems firing native filesystem events on the guest OS.

Suggested use:

On the host OS, you need to listen to filesystem events and forward them to your VM using the listen script:

$ listen -f 127.0.0.1:4000

Remember to configure your VM to forward the appropriate ports, e.g. in Vagrantfile: config.vm.network :forwarded_port, guest: 4000, host: 4000

Then, on your guest OS, listen to the network events but ensure you specify the host path $ bundle exec guard -o '10.0.2.2:4000' -w '/projects/myproject'

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top