nothing-special-here
nothing-special-here

Reputation: 12588

Spork doesn't reload code

I am using following gems and ruby-1.9.3-p194:

Full list of used gems is available in this Gemfile.lock or Gemfile.

And I am using this configuration files:

If I modify any model (or custom validator in app/validators etc) reloading code doesnt works.

I mean when I run specs (hit Enter on guard console) Spork contain "old code" and I got obsolete error messages. But when I manually restart Guard and Spork (CTRC-C CTRL-d guard) everything works fine. But it is getting tired after few times.

Questions:

Can somebody look at my config files please and fix error which block updating code.

Or maybe this is an issue of newest Rails version?


PS This problem repeats and repeats over some projects (and on some NOT). But I haven't figured out yet why this is happens.

PS2 Perhaps this problem is something to do with ActiveAdmin? When I change file in app/admin code is reloaded.

Upvotes: 11

Views: 3665

Answers (7)

yellowaj
yellowaj

Reputation: 465

I had the same problem. Tests were reloaded and ran successfully for changes to model_spec.rb. When I made changes to the model.rb file the tests were re-run, however the code seemed to be cached - so the changed were not applied.

It required a combination of a few answers to get things working:

# /config/environments/test.rb
config.cache_classes = !(ENV['DRB'] == 'true')

# spec_helper.rb
Spork.each_run do
  .....
  ActiveSupport::Dependencies.clear
end

I also updated spork to (1.0.0rc3) and replaced the spork gem with spork-rails, as mentioned by @23inhouse above. However, I did not see any difference between either gem in the gemfile although upgrading spork may have had an effect.

Hopefully this helps someone else not spend any more hours banging their head against the wall.

Upvotes: 5

nothing-special-here
nothing-special-here

Reputation: 12588

Workaround:

# config/environments/test.rb
config.cache_classes = false

But it is "double-edged sword".

Specs run now ~2.0x time longer. But it is still faster than restarting again and again Spork.


Update 28.06.2013

Use Zeus. It works perfectly. Benchmarks are at the bottom..

If you are using 1.9.3 consider installing special patches which REALLY speed up loading app.

RVM patchsets

rbenv instructions

Background & Benchmark:

I have a quite large 1.9.3 app and I wanted to speedup app loading, Spork doesn't work so I started looking for other solutions:

I write a empty spec to see how long it takes to load my app

-/spec/empty_spec.rb

require 'spec_helper'

describe 'Empty' do

end

plain 1.9.3

time rspec spec/empty_spec.rb 64,65s user 2,16s system 98% cpu 1:07,55 total

1.9.3 + rvm patchsets

time rspec spec/empty_spec.rb 17,34s user 2,58s system 99% cpu 20,047 total

1.9.3 + rvm patchsets + zeus

time zeus test spec/empty_spec.rb 0,57s user 0,02s system 58% cpu 1,010 total [w00t w00t!]

Upvotes: 8

23inhouse
23inhouse

Reputation: 1927

Spork got cleaned up and some functionality was extraced.

https://github.com/sporkrb/spork-rails

add this to your Gemfile

gem 'spork-rails'

Upvotes: 2

B Seven
B Seven

Reputation: 45941

Fixed the same problem by adding more to the spork.each_run method.

Rails 3.2.2

Also, I recommend running one test a time. It's much faster, less noisy, and we normally work on one test at a time anyway.

rspec spec -e 'shows answer text'

I find it is faster and easier than using Guard because I was just sitting around waiting for Guard to finish. Also, Guard did not always reload the right files and run the right tests when I made a change.

spec_helper.rb file:

require 'spork'

Spork.prefork do
  ENV['RAILS_ENV'] ||= 'test'

  require File.expand_path('../../config/environment', __FILE__)
  require 'rspec/rails'
  require 'rspec/autorun'
  require 'capybara/rspec'
  require 'capybara/rails'

  # Requires supporting ruby files with custom matchers and macros, etc,
  # in spec/support/ and its subdirectories.
end

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

  RSpec.configure do |config|
    # config.mock_with :mocha
    # config.mock_with :flexmock
    # config.mock_with :rr
    config.mock_with :rspec

    # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
    config.fixture_path = "#{::Rails.root}/spec/fixtures"

    # If you're not using ActiveRecord, or you'd prefer not to run each of your
    # examples within a transaction, remove the following line or assign false
    # instead of true.
    config.use_transactional_fixtures = true

    # If true, the base class of anonymous controllers will be inferred
    # automatically. This will be the default behavior in future versions of
    # rspec-rails.
    config.infer_base_class_for_anonymous_controllers = false

    config.include RequestHelpers, :type => :request

    config.before :suite do
      DatabaseCleaner.strategy = :truncation
      DatabaseCleaner.clean_with :truncation
    end

    config.before :each do
      DatabaseCleaner.start
    end

    config.after :each do
      DatabaseCleaner.clean
    end

    config.include(MailerHelpers)
    config.before(:each) { reset_email }
  end
  # This code will be run each time you run your specs.
end

Upvotes: 0

Andrea Reginato
Andrea Reginato

Reputation: 1338

In my case the problem was draper. It didn't allow spork to reload the models.

Spork.prefork do
  ENV['RAILS_ENV'] ||= 'test'

  # Routes and app/ classes reload
  require 'rails/application'
  Spork.trap_method(Rails::Application::RoutesReloader, :reload!)
  Spork.trap_method(Rails::Application, :eager_load!)

  # Draper preload of models
  require 'draper'
  Spork.trap_class_method(Draper::System, :load_app_local_decorators)

  # Load railties
  require File.expand_path('../../config/environment', __FILE__)
  Rails.application.railties.all { |r| r.eager_load! }
  ...

Just remember to insert the trap method for Draper before loading the environment.

Upvotes: 3

Howard Yeh
Howard Yeh

Reputation: 61

Great as Spork is, it seems to break on every Rails upgrade :(

On Rails, 3.2.3, I've added this snippet in spec/spec_helper.rb to forcibly reload all ruby files in the app directory.

Spork.each_run do
  # This code will be run each time you run your specs.
  Dir[Rails.root + "app/**/*.rb"].each do |file|
    load file
  end
end

Upvotes: 4

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230441

Alternatively, you can add guards for your models, controllers and other code. It'll make guard reload spork when any of these files change.

guard 'spork',
      :rspec_env => {'RAILS_ENV' => 'test'} do
  watch(%r{^app/models/(.+)\.rb$})
  watch(%r{^lib/(.+)\.rb$})
end

Upvotes: 7

Related Questions