Spork doesn't reload code
Asked Answered
A

7

11

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

  • rails 3.2.3

  • rspec-rails 2.9.0

  • spork 1.0.0rc2

  • guard-spork 0.6.1

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.

Aggravation answered 24/4, 2012 at 9:44 Comment(0)
A
8

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!]

Aggravation answered 26/4, 2012 at 14:46 Comment(3)
Yes but.. it isn't "pure" benchmark. I just run specs few times with that option and without.Aggravation
In my project, not caching classes causes intermittant errors from FactoryGirl definitions that vanish after some Spork runs. Caching classes fixes that, but them I'm back to the original error...Dall
Zeus is VERY buggy. Especially on VMs.Allanallana
R
7

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
Roncesvalles answered 26/4, 2012 at 14:54 Comment(8)
I tested that approach but... got tired after several reloads.Aggravation
Tired of waiting a few secs? :)Roncesvalles
Yes. :) It takes ~20-30s to reload Spork (on my PC). I typically runs single specs (when I made a change in model while refactoring etc).Aggravation
You must have a huge app. Or antique PC :) My spork takes 5-7 secs to reload.Roncesvalles
The second one option. :D It is a laptop from 2009 year.Aggravation
5-7 seconds is still unacceptable if you have to wait that long before running rspec every time you hit saveMagma
This is great for reloading support files in the spec/support directory, thanksIllyricum
This method worked well for me with RSpec and Sinatra. Sinatra doesn't have the autoloading features that Rails does, so this was the best option I found for getting modified classes into RSpec with Guard and Spork.Tavia
J
5

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.

Jaques answered 2/7, 2013 at 16:23 Comment(0)
Z
4

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
Zero answered 26/6, 2012 at 9:13 Comment(2)
Looks like the only reliable way (as of now). Sure it slows things down, but overall it is still faster than no spork at allIndentation
I take it back. Don't do that. It does not unload classes. Which leads to things like after_create registered twice and so on.Indentation
O
3

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.

Offspring answered 31/7, 2012 at 17:21 Comment(0)
R
2

Spork got cleaned up and some functionality was extraced.

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

add this to your Gemfile

gem 'spork-rails'

Rania answered 25/1, 2013 at 2:3 Comment(1)
Thanks for the repo URL. I will check it out.Aggravation
F
0

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
Fiedling answered 12/8, 2012 at 20:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.