Closed dchelimsky closed 14 years ago
Great news. Yes, I'm betting models are getting preloaded. It's a nasty duck punch to make spork do it's magic with Rails, unfortunately. I'm hoping the Rails 3 cleans up it's architecture. I'm dreading figuring out how to get the tests running with Bundler... there's so much uncertainty around it still.
Are you at RC this week?
No, at home.
What should I do to avoid this issue?
If I set config.cache_classes to false I have very many test fails of my apps.
I pushed spork 0.8.4 out, it includes a patch contributed by Elliot Winkler that fixes the bundler/spork conflict with the diagnoser mode.
Can you run spork -d
and see what's preloading it? We must intervene, with the best means available, to make the application not preload the models.
Tim
My system: ruby 1.9.3dev (2010-05-08 trunk 27674) [x86_64-linux] spork (0.8.4)
$ spork -d > out.txt
https://gist.github.com/bfb318c6375c444ed395
And my spec_helper: https://gist.github.com/1d92348b08b71a5fc798
I runned spork. Then I added error in my user.rb.
I run rspec with --drb and get no error. Then I run rspec without drb and saw an error.
$ rspec spec/models/user_spec.rb --drb
...
Finished in 0.0281 seconds
3 examples, 0 failures
$ rspec spec/models/user_spec.rb
/usr/lib/ruby/gems/svn/gems/activerecord-3.0.0.beta3/lib/active_record/base.rb:1141:in
method_missing': undefined method
s' for #Class:0x0000000474caa8 (NoMethodError)
same problem that petRUShka with Ruby 1.8.7 & Rails 3.0.0.beta4 (config.cache_classes to false => many test fails) and model modification not reloaded.
my spork -d: http://gist.github.com/435745
I can confirm this issue with the latest version of REE (2010.02) - model modifications are not reloaded
I have a similar issue, however only some models are reloading. My User model does not reload, but my Order model does... (using REE 2010.02) my spork -d: http://gist.github.com/452989 I'm also using Mongoid instead of ActiveRecord
Any news about the resolution of this problem?
No, but I did just get the spork cucumber testsuite to work with bundler (as in, it can test with a rails project generated using a bundler gemfile)! This is, in my opinion, a HUGE step forward and has been a primary hold-back rails 3.0 support.
Great to hear that, thk for the update!
OK... so spork totally isn't compatible with rails 3.0 right now. It's been using the Unknown framework, which basically leaves you on your own to make stuff you want loaded each time is done in an each_run block....
It'll be easy to fix?
For me this solution does reload models: http://github.com/rspec/rspec-core/issues/issue/62/#issue/62/comment/305544
Same here, the solution on the rspec-core issues works for me too. Would be great now that rails 3.0 is out of the closet that spork worked with it :-)
All interested parties: try out 0.9.0 RC2. At least the integration tests show that model reloading is occurring.
I've still got some doubts about observers triggering pre-loading of models, and have noticed that mongoid seems to want to eagerload the model universe as well.
Tim
So, do we have to remove the fix from http://github.com/rspec/rspec-core/issues/issue/62/#issue/62/comment/305544 after we've upgraded to 0.9.0 RC2 ? or else ?
Hmm, I don't know. Try it and see? (it shouldn't be preloading application files.. although some things may still trigger it).
It seems like it's best to avoid preloading any application files (app// and lib/), but I can see the merit in that being an easy, reliable solution (although it feels a little messy).
... so... you tell me?
Ok, so, I upgraded to 0.9.0.rc2, removed the fix from the rspec-core issue 62's comment, and I ran the tests once, changed a model so that some tests should fail, and with spork, the model was not reloaded, it was still giving me a all's ok result, restarting spork gives me the errors I was expecting, correcting the model back still gives me the errors. Putting back the fix gives me back the expected result. So, all in all, no, not fixed :-)
OK :) there's likely something else triggering the models to load during boot. Do you have observers loaded? Can you post the interesting pieces from the result of `spork -d'
No observers. Here's the spork -d
output :
Using RSpec
Preloading Rails environment
Loading Spork.prefork block...
- Spork Diagnosis -
-- Summary --
config/application.rb
config/boot.rb
config/environment.rb
config/environments/test.rb
config/initializers/backtrace_silencers.rb
config/initializers/devise.rb
config/initializers/haml.rb
config/initializers/inflections.rb
config/initializers/mime_types.rb
config/initializers/new_rails_defaults.rb
config/initializers/secret_token.rb
config/initializers/session_store.rb
config/routes.rb
spec/spec_helper.rb
vendor/plugins/dynamic_form/lib/action_view/helpers/dynamic_form.rb
vendor/plugins/jrails/lib/jquery_selector_assertions.rb
vendor/plugins/jrails/lib/jrails.rb
huh, I'll be. It doesn't show that you're models are being preloaded (scratches head until bald spot occurs)
I'm seriously stumped here.
I'm also using rspec 2 / Rails 3.0.0 / Spork '0.9.0.rc2' and it is not reloading models either. I can't use the hack above because I'm also using database_cleaner with my Capybara/Selenium Webdriver tests - gives me a wierd TypeMismatch error - somehow the classes are defined twice.
I resorted to doing the following:
Spork.each_run do
silencewarnings do Dir["#{Rails.root}/app/*/_.rb"].each { |f| load f } end end
spork -d didn't reveal anything but I think I've found out where the models are being preloaded - via factory_girl
I did this by placing the following lines on top of one of my models (person.rb), and then tail'ed the test.log:
begin raise rescue => e Rails.logger.info [e, e.backtrace].join("\n") end
http://pastie.org/private/vheva2yln2qtfywhwrtqw
I wonder if it's possible to trap the method like you do for other things...
Steve
So weird that it is preloaded but not showing up in your `spork -d'. I'll have to try and play around with a test project and see if I can reproduce here.
Trapping the method seems like the best approach. The find_definitions method looks like the best bet.
Try this:
Spork.trap_class_method(Factory, :find_definitions)
Put it so it gets called before the environment is loaded, and after factory_girl is loaded (you may need to manually require...)
OK I've figured it out.
It was factory_girl_rails that was causing the preload (which wasn't picked up by spork -d) but it is required as a gem so I moved the gem to its own 'development' only group so it isn't loaded by spork prefork:
group :development do gem 'spork', '0.9.0.rc2' gem 'factory_girl_rails' end
When it comes to spec_helper I manually require it myself (I put all my factories in spec/factories) - you might change that:
Spork.each_run do require 'factory_girl' Dir[File.expandpath(File.join(File.dirname(FILE),'factories','*','_.rb'))].each {|f| require f} end
The models seem to reload properly now.
One problem I had once i finally got spork to reload my models properly was that I could not run a db:reset. I got errors complaining about factory girl not being able to find my database tables, which makes sense since the reset just dropped them!
With the changes in the comment above I no longer needed to load FG within any of the Gemfile groups so i made a separate group that still gets loaded by bundler, but doesn't load FG in any of my environments, leaving spork to load it manually.
group :noload do
gem 'factory_girl_rails'
end
I'm still not exactly sure what caused db:reset to flip out, but this little hack fixed it.
I'm having this same problem with factory girl.
I can't require factory_girl in each_run because I get an error
Exception encountered: #<LoadError: no such file to load -- factory_girl>
Very frustrating. Any suggestions?
https://github.com/Cluster444/zmchapters/blob/74df4d6bb85d3cf25afae028302a6b23d5d07700/Gemfile
That's how i've setup factory girl and it seems to work ok. I've only ever run into a problem with my User model not reloading, the rest of them reload fine.
Hi there, this is the code I settled on with a co-worker today and it seems to do the trick. Put it in application.rb :
ActionDispatch::Callbacks.after do
# Reload the factories
return unless (Rails.env.development? || Rails.env.test?)
unless Factory.factories.blank? # first init will load factories, this should only run on subsequent reloads
Factory.factories.clear
Factory.find_definitions.each do |location|
Dir["#{location}/**/*.rb"].each { |file| load file }
end
end
end
This is my Spork.prefork block
{Spork.prefork do
require File.expand_path(File.join(File.dirname(FILE),'..','config','environment'))
require 'spec/autorun'
require 'ruby-debug'
require 'webrat'
require 'webrat/integrations/rspec-rails'
require 'db/seeds'
require 'authlogic/test_case/mock_request'
require 'authlogic/test_case/mock_cookie_jar'
require 'authlogic/test_case/mock_controller'
require 'merchant/utils'
include Merchant::Utils
end}
when i ran spork -d its only show loaded confin/initializers/..files and spec_helper ......why?
is the same issue?
I've written a wiki entry on this: https://github.com/timcharper/spork/wiki/Troubleshooting
I can verify that the suggestion in the wiki does not solve the problem with FactoryGirl 2.1.0 & Rails 3.1. I found it necessary to reload all the models, otherwise changes would not be picked up.
Spork.each_run do
require 'factory_girl_rails'
# reload all the models
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
load model
end
end
I'll update the wiki article now.
I found it necessary to reload all the models, otherwise changes would not be picked up.
This solution works but I'm getting a lot of warnings on every test run because i have constants defined in my models
/home/morr/develop/site/app/models/group_join_policy.rb:2: warning: already initialized constant Free /home/morr/develop/site/app/models/group_join_policy.rb:7: warning: already initialized constant ByOwnerInvite
The problem is the models are getting preloaded. Spork states that any code that is preloaded will be cached from run to run. Use spork -d | less
to get a report of what files are loaded, and a stack trace of what was responsible for triggering the load.
I just :
Spork.each_run do
require 'factory_girl_rails'
end
And in my Gemfile :
gem 'factory_girl_rails', :require => false
+1 on @jc00ke 's last comment. I tried everything else in this thread to no avail on Rails 3.1.1 with FactoryGirl. I have to explicitly reload all the models.
When I run spork -d | less
it doesn't say that it's loading app/models prefork.
Finally, once I add foreman or guard into the mix, event @jc00ke 's advice doesn't fix the issue :-(
I also rely on a workaround like wakiki and jc00ke's to make models reload with spork:
Spork.each_run do
...
# Hack to ensure models get reloaded by Spork - remove as soon as this is fixed in Spork.
# Silence warnings to avoid all the 'warning: already initialized constant' messages that
# appear for constants defined in the models.
silence_warnings do
Dir["#{Rails.root}/app/models/**/*.rb"].each {|f| load f}
end
end
Edit: got silence_warnings to work
Is this issue solved?, I'm using 1.0.0rc and get the same behavior.
Ok, I switched to fork-rails and it works now.
I just got rspec-2 working with spork and rails-3. I haven't had a chance to investigate why yet, but with this configuration we need to set config.cache_classes = false to get models to reload. This suggests that rails is eager loading models during the prefork (which in my case is not asking to load anything under app). Something we can manage from spork?