Spork & Rails 3.1 engine: helpers are not reloaded - ruby-on-rails

I'm developing a Rails 3.1 engine and want to test it. I use RSpec for this, and everything works nicely, but when trying to use Spork, I have the problem that my helpers are not correctly reloaded.
I read a lot about a similar problem with models, and I came up with the following possible fix:
# my_engine/spec/spec_helper.rb
ActiveSupport::Dependencies.clear
ActiveRecord::Base.instantiate_observers
Dir[File.join(File.dirname(__FILE__), '..', 'app', 'helpers', '*.rb')].each do |file|
require file
end
# my_engine/spec/dummy/config/environments/test.rb
Dummy::Application.configure do
# ...
config.cache_classes = !(ENV['DRB'] == 'true') # Ensure that classes aren't cached when using Spork.
# ...
end
This works as far as it definitely is reloading ever helper file (I added a breakpoint to check this), but the changes are not reflected within the tests, only a restart of Spork does. Maybe it's because helpers are modules, and the tests don't rely on the module but on the classes that implement the modules, so the modules are properly reloaded but not properly mixed in??
At the time being, I'm just putting all intitializer code into the each_run block:
# Configure Rails Environment
ENV["RAILS_ENV"] = "test"
require File.expand_path("../dummy/config/environment.rb", __FILE__)
require 'rspec/rails'
Rails.backtrace_cleaner.remove_silencers!
# Load support files
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
RSpec.configure do |config|
config.use_transactional_fixtures = true
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
end

I have done a lot of research about this topic, and I've written about in these two blog posts:
How to Develop Rails 3.1 Engines with Ease: Part I – The engine
How to Develop Rails 3.1 Engines with Ease: Part II – The gem
Regarding especially to my question above: I can imagine that it didn't work because I didn't require 'rspec/autorun' in the Spork.prefork block, but I'm not completely sure.
Here's the spec_helper.rb for my current engine (which successfully reloads everything as needed):
require 'rubygems'
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../dummy/config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.use_transactional_fixtures = true
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.infer_base_class_for_anonymous_controllers = false
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end

Related

Rspec loading old schema

I am working on a legacy project (recently upgraded from rails 4.1 to 5.2) and I had to change an association table. Before:
reports had many clients and clients had many reports. Now I have created a ClientsReport table than not only holds the client_id and reports_id but also has an id as primary_key and a can_manage (boolean).
Testing with rspec it is giving me an error when calling reports_clients.for(report).first.can_manage
saying unKnownAttribute can_manage for <ClientsReport client_id: 1, report_id:3> no sign if id nor can_manage
So it looks like it is using the old schema.
Also tried adding ActiveRecord::Migration.maintain_test_schema! as suggested here but I am not sure
I tried running rake:db:prepare but it threw me a bunch of errors and now looks like I broke the test db, as I was having 4 failing tests and now I have 166...
My spec_helper.rb looks like this:
Spork.prefork do
require 'simplecov'
SimpleCov.start 'rails'
# 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 'devise'
require './spec/controllers/controller_helpers.rb'
# 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|
config.include Devise::Test::ControllerHelpers, type: :controller
config.include ControllerHelpers, type: :controller
config.include Capybara::DSL
# ## 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 = 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.infer_spec_type_from_file_location!
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
config.include FactoryGirl::Syntax::Methods
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end
You can completely reset the test DB with this command, after making sure your schema is up to date.
bin/rails db:environment:set db:drop db:create db:schema:load RAILS_ENV=test

RSpec 3.1 undefined method `feature' for main:Object

I´m going through the rather painful upgrade to RSpec 3.1. I have several feature specs which worked in RSpec 2.99 that raise:
undefined method `feature' for main:Object
I noticed that I have to use RSpec.describe in my other specs since they are are no longer attached to the main object. What would the equivalent call for feature be?
In my features I require 'rails_helper'
require 'rails_helper'
feature 'Facebook Authentiation' do
...
end
spec/rails_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rails/application'
# Add additional requires below this line. Rails is not loaded until this point!
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
# 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
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location
config.infer_spec_type_from_file_location!
end
spec/spec_helper.rb
#
See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
# assertions if you prefer.
config.expect_with :rspec do |expectations|
# This option will default to `true` in RSpec 4. It makes the `description`
# and `failure_message` of custom matchers include text for helper methods
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
# rspec-mocks config goes here. You can use an alternate test double
# library (such as bogus or mocha) by changing the `mock_with` option here.
config.mock_with :rspec do |mocks|
# Prevents you from mocking or stubbing a method that does not exist on
# a real object. This is generally recommended, and will default to
# `true` in RSpec 4.
mocks.verify_partial_doubles = true
end
# These two settings work together to allow you to limit a spec run
# to individual examples or groups you care about by tagging them with
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
# get run.
config.filter_run :focus
config.run_all_when_everything_filtered = true
# Limits the available syntax to the non-monkey patched syntax that is recommended.
# For more details, see:
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
config.disable_monkey_patching!
# Many RSpec users commonly either run the entire suite or an individual
# file, and it's useful to allow more verbose output when running an
# individual spec file.
if config.files_to_run.one?
# Use the documentation formatter for detailed output,
# unless a formatter has already been configured
# (e.g. via a command-line flag).
config.default_formatter = 'doc'
end
# Print the 10 slowest examples and example groups at the
# end of the spec run, to help surface which specs are running
# particularly slow.
config.profile_examples = 10
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = :random
# Seed global randomization in this process using the `--seed` CLI option.
# Setting this allows you to use `--seed` to deterministically reproduce
# test failures related to randomization by passing the same `--seed` value
# as the one that triggered the failure.
Kernel.srand config.seed
end
Gemfile
# ...
group :development, :test do
gem 'rspec-rails', '~> 3.1.0'
end
# ...
group :test do
# ...
gem 'capybara', '~> 2.4.3'
end
It looks like your forgot to require capybara at your spec/rails_helper.rb
require 'capybara/rspec'
Also you can try to remove this line:
config.disable_monkey_patching!
Or check if capybara adds feature method to Rspec namespace:
RSpec.feature "My feature" do
...
end
I've faced the same issue with rails 4.2 even though I've had
require 'capybara/rspec' in rails_helper.rb
and
require 'spec_helper' in feature spec.
Solution is to require 'rails_helper' in feature spec as well.
In my case the problem was that I had the
require "spec_helper"
line lower in rails_helper.rb.
When I moved it at the top, everything went back to normal.
For your reference, my rails_helper.rb first lines now are:
require "spec_helper"
ENV["RAILS_ENV"] ||= "test"
require File.expand_path("../../config/environment", __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require "rspec/rails"
I had to use the following in my problem which is a combination of previous answers:
spec/features/visitors/navigation_spec.rb
require 'spec_helper'
require 'capybara/rspec'
RSpec.feature 'Navigation links', :devise do
...
end
spec/rails_helper.rb
require 'capybara/rspec'
spec/spec_helper.rb
config.disable_monkey_patching = false

How to put RSpec/Capybara tests outside of the spec/requests directory?

For some reason my team does not want our acceptance tests to exist in the spec/requests directory. Instead, they would like them placed in a new directory called acceptance that exists outside of the spec directory structure. So, my first question is, using RSpec, Capybara and capybara-webkit, is this even possible?
Here is my acceptance_spec_helper.rb file
require 'rubygems'
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.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
# Capybara.javascript_driver = :webkit
RSpec.configure do |config|
config.include RSpec::Rails::RequestExampleGroup, :type => :request, :example_group => {
:file_path => config.escaped_path(%w[acceptance])
}
# 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
end
However, it does not seem that the application is actually being run in order to be tested.
And please, do not just say to put the tests back in the spec/requests directory without some very strong arguments to back up why that is the only option.
I've done something similar where I had my specs in spec/acceptance, tagged them with :acceptance => true, and ran them with a separate rake task rake spec:acceptance
Check out this gist- https://gist.github.com/3858851.
Hope it helps

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