rspec failing - Bundle.require(*Rails.groups) - ruby-on-rails

I have been running Rspec recently but realised it was completely deleting my development database. I believe the cause of this is the failure of setting 'RAILS_ENV' at the beginning of 'rails_helper.rb' and therefore database cleaner is clearing the development db as well as the test db. Unsure if this is actually what is happening.
In order to combat the issue of
[1] RAILS_ENV
=> nil
[2] ENV['RAILS_ENV']
=> nil
I decided to set ENV['RAILS_ENV'] at the beginning of the file but this appears to break everything
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
after some digging, it's a call to 'Bundle.require(*Rails.groups)' that actually breaks and the response is
[1] Bundle.require(*Rails.groups)
=> NameError: uninitialized constant FactoryBotFactory::BaseFactory
I am calling this prior to loading the application due to an issue of setting constants throughout the application rather than using "ENV['SOMETHING']". This works fine locally and in production and even works for rspec... but not if I set 'ENV['RAILS_ENV']'
application.rb
Bundler.require(*Rails.groups)
Dotenv::Railtie.load unless Rails.env.production?
require_relative 'constants'
module MyApp
class Application < Rails::Application

For anyone else that may come across this problem.
We found that there is an additional configuration available for DatabaseCleaner when using active record.
When you use the standard setup, database cleaner is set to
DatabaseCleaner[:active_record].db = :default
which i believe is then setting the db as development.
We added this line directly after the require statement for the gem and it appears to be working find.
require 'database_cleaner-active_record'
DatabaseCleaner[:active_record].db = :test
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
We also removed the line
ENV['RAILS_ENV'] = 'test'

Related

Spork doesn't reload code

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:
Guardfile
.rspec
spec_helper.rb
factories.rb
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.
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!]
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
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.
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
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.
Spork got cleaned up and some functionality was extraced.
https://github.com/sporkrb/spork-rails
add this to your Gemfile
gem 'spork-rails'
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

RSpec+Capybara request specs w/ JS not working

I cannot get request specs working when using Javascript.
My specs pass if I run them without Javascript (the page is built to work with or without JS).
Specifically, the specs fail when I do assertions like Post.should have(1).record.
Capybara just doesn't pick up the records from the DB, and the database is not cleaned between runs.
I've tried using DatabaseCleaner with transactional fixtures disabled - the common approach to this, I guess. No dice.
I've also tried (and, would ideally prefer) running without DatabaseCleaner, using transactional fixtures and forcing AR to share the same connection between threads (a patch described by José Valim). Again, no dice.
Additionally, I've also tried switching between Capybara-webkit and Selenium - the issue persists.
I've put up a sample app with just a basic Post scaffold, that replicates the problem: https://github.com/cabgfx/js-specs
There's a spec_helper.rb with transactional fixtures and AR shared connection, and a spec_helper_database_cleaner.rb for the other scenario.
I normally use Spork, but I've disabled it in both spec_helper.rb files, just to eliminate a potential point of failure (in both apps; the "real" one and the sample app).
I develop locally using Pow on a Macbook Air, running OS X 10.7.3 with MRI 1.9.3 thru RVM. (I also tried on 1.9.2).
Hope I'm making sense - any guidance/help/pointers are greatly appreciated!
Matt - thanks a lot for taking time to assist me!
I tried setting it up with your spec_helper, using Selenium as the javascript driver.
The spec still failed - but I could see the correct behavior being executed in Firefox...
Then it dawned on me, that the problem might occur because of Capybara not waiting for AJAX requests to finish.
I then reverted to my initial spec_helper (with Spork and no DatabaseCleaner), and simply used Capybara's wait_until { page.has_content? "text I'm inserting with JS" }.
I updated the sample app, and just added sleep 1 in the request spec, so you can see for yourself. It now works with and without Spork, and the AR monkey patch seems to work perfectly.
I have tried your code with the spec_helper.rb listed below and the test passes. Note that the syntax for triggering database cleaner is a bit different than in your spec_helper_database_cleaner.rb.
We're using this in production, and we've also tried the modification suggested by Jose Valim but it didn't work for us - this did.
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'
# Add this to load Capybara integration:
require 'capybara/rspec'
require 'capybara/rails'
include Capybara::DSL
# 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}
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# 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 = false
# 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
# Include sign_in & sign_out for tests
# config.include Devise::TestHelpers, :type => :controller
# Use database_cleaner to ensure a known good test db state as we can't use
# transactional fixures due to selenium testing
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
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end
José's suggestion worked for me but not when I used Spork. But adding this to spec_helper.rb did:
Spork.prefork do
RSpec.configure do |config|
# Make it so poltergeist (out of thread) tests can work with transactional fixtures
# http://www.opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/#post-441060846
ActiveRecord::ConnectionAdapters::ConnectionPool.class_eval do
def current_connection_id
Thread.main.object_id
end
end
end
end
Source: http://www.opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/#post-441060846

Spork: how to refresh validations and other code?

I've been using spork all day, and most of the time it is a really great.
However, I am often running into a few problems where I need to restart Spork in order for my tests to pass... and now I'm wondering if it's more trouble than it's worth. I am new at ruby, so sometimes I can't predict if the error is due to a refresh problem, or if the error is due to my unfamiliarity with Ruby and Rails.
What do I need to put into Spork.each_run block so that my validations and other things are refreshed so that I don't have to restart the spork server?
Thanks
EDIT: If you can upgrade to Ruby 2.0 this is your best bet. It is fast enough and will let you work in regular way without the need for tools like Spork, Zeus, and ect. And in essence you won't need anything I wrote below.
If you still need some speed bump while developing check out the Fast Rails Commands cast.
Well yes, you want to reload Spork if you changed environment, initializer or spec_helper files (and for that guard-spork is perfect), but not when you updated one of your classes (models) as this would deny the purpose of tools like spork. I had the very same issue: I could delete all methods in a model, and tests would still pass, because Spork hold "old" model class in memory. Restarting Spork was required.
Reason:
Some plugins cause the model code to be preloaded so some work is required to block that from happening.
https://github.com/sporkrb/spork/issues/37
https://github.com/sporkrb/spork/issues/94
You want to prevent model code preloaded, as this will not "reload" them if you make any changes (like with validations).
Solutions:
Depends from gems that are involved. In my case, I had to deal with Devise and FactoryGirl, but in essence, you do it by using Spork.trap_method as described on wiki: https://github.com/sporkrb/spork/wiki/Spork.trap_method-Jujitsu
Additionally you can run spork -d to get a list of files that are preloaded, it may be helpful to track which gems may be involved in causing this issue.
Example:
Rails 3.0.x + Rspec2 + Spork 0.9.0.rcX + Capybara + Devise + FactoryGirl
# spec/spec_helper.rb
Spork.prefork do
# 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 'capybara/rspec'
require 'capybara/rails'
# set "gem 'factory_girl', :require => false" in Gemfile
require 'factory_girl'
# deal with Devise
require "rails/application"
Spork.trap_method(Rails::Application, :reload_routes!)
require File.dirname(__FILE__) + "/../config/environment.rb"
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.mock_with :rspec
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
# Devise controller test helpers:
config.include Devise::TestHelpers, :type => :controller
end
end
Spork.each_run do
# deal with factory girl
Factory.definition_file_paths = [File.join(Rails.root, 'spec', 'factories')]
Factory.find_definitions
end
Please note that config.cache_classes = true need to be set to true in test environment, otherwise you may get errors from gems like FactoryGirl.
This made my model tests (specs) run quickly, and "reload" them every time I save a file and fire rspec.
EDIT: If you're running on Ruby 1.9.3 you can try out an interesting alternative: Zeus - https://github.com/burke/zeus
Use Guard to reload Spork when you update your classes Guard::Spork allows to automatically & intelligently start/reload your RSpec/Cucumber Spork server(s).
https://github.com/guard/guard-spork
http://flux88.com/2011/04/using-guard-spork-with-mongoid-devise/
From http://www.rubyinside.com/how-to-rails-3-and-rspec-2-4336.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+RubyInside+%28Ruby+Inside%29 :
A minor snafu will remain, though. If
you update app/models/person.rb, the
change won't take effect in your tests
since Spork has the old Person still
in memory. One way around this is to
edit config/environments/test.rb and
change:
config.cache_classes = true
To:
config.cache_classes = false
With more recent versions of Factory Girl, you don't need to do much. First, add FactoryGirl.reload in Spork.each_run. If you have factories with the class parameter, they should be string.
factory :my_model, class: 'MyModel' do...
instead of
factory :my_model, class: MyModel do...

Cucumber prevent from clearing database

due to a heavy growing project I'm running into the trouble that the database rebuild process of cucumber really takes a long time.
Since it is a application where the actual content of the table doesn't matter, I'd like to skip the rebuild process.
Unfortunately wether cucumber nor database_cleaner seem to support this, doesn't they?
My cucumber env settings may be found below
Thanks and many regards,
Joe
ENV["RAILS_ENV"] ||= "cucumber"
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
require 'cucumber/rails/world'
require 'cucumber/rails/active_record'
require 'cucumber/web/tableish'
require 'capybara/rails'
require 'capybara/cucumber'
require 'capybara/session'
require 'cucumber/rails/capybara_javascript_emulation'
Capybara.default_selector = :css
ActionController::Base.allow_rescue = false
Cucumber::Rails::World.use_transactional_fixtures = false
Capybara.default_driver = :selenium
if defined?(ActiveRecord::Base)
begin
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
rescue LoadError => ignore_if_database_cleaner_not_present
end
end
An easy way to stop database_cleaner from cleaning one of your tables is to configure it like this:
DatabaseCleaner.strategy = :truncation, {:except => %w[states]}
In this example, once the table states is loaded with information, it doesn't clean it.

Can't get rspec, spork and debugger to play nice

Given I am a dumb programmer
and I am using rspec
and I am using spork
and I want to debug ...mmm...let's saaay, a spec for Phone.
Then, where should I put the "require 'ruby-debug'" line in order to halt processing at a particular point in the phone_spec.rb? (All I'm asking for is a big fat arrow that even a challenged programmer could see :-3 )
I've tried many locations, and unless I didn't test them correctly, there's something weird going on:
In spec_helper.rb at the following locations:
require 'rubygems'
require 'spork'
<= TRIED IT HERE
ENV["RAILS_ENV"] ||= 'test'
Spork.prefork do
require File.dirname(__FILE__) + "/../config/environment" #unless defined?(RAILS_ROOT)
require 'spec/autorun'
require 'spec/rails'
require 'machinist/active_record'
require 'faker'
require 'sham'
<= TRIED IT HERE
end
Spork.each_run do
require File.expand_path(File.dirname(__FILE__) + "/blueprints")
<= TRIED IT HERE
end
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
Spec::Runner.configure do |config|
config.use_transactional_fixtures = true
config.use_instantiated_fixtures = false
config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
config.before(:all) { Sham.reset(:before_all) }
config.before(:each) { Sham.reset(:before_each) }
<= TRIED IT HERE
end
I'm running Spork and Autospec with ruby-debug. Later versions of Spork have an external ruby-debug library you can require, it's experimental so use at your own risk. In my prefork block I just have :
require 'spork/ext/ruby-debug'
It'll break out to a debug session in the terminal you have Spork running. There are methods etc to initiate remote connection setup and so on, and recent commits have had updates and fixes applied to their debugging functionality so it's under active development. Hopefully it'll be core and tested soon ...
I've always put it in config/environments/test.rb and the put the debugger at the breakpoint in my app code (as opposed to the spec).

Resources