Skip to content

Instantly share code, notes, and snippets.

@libbyschuknight
Created January 4, 2018 20:47
Show Gist options
  • Select an option

  • Save libbyschuknight/13c7f9c80a2aaab0b4f51f656fe787f6 to your computer and use it in GitHub Desktop.

Select an option

Save libbyschuknight/13c7f9c80a2aaab0b4f51f656fe787f6 to your computer and use it in GitHub Desktop.
Getting fixtures working for features when using cucumber
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
# It is recommended to regenerate this file in the future when you upgrade to a
# newer version of cucumber-rails. Consider adding your own code to a new file
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
# files.
require 'cucumber/rails'
require_relative 'fixture_access'
# Capybara defaults to CSS3 selectors rather than XPath.
# If you'd prefer to use XPath, just uncomment this line and adjust any
# selectors in your step definitions to use the XPath syntax.
# Capybara.default_selector = :xpath
# By default, any exception happening in your Rails application will bubble up
# to Cucumber so that your scenario will fail. This is a different from how
# your application behaves in the production environment, where an error page will
# be rendered instead.
#
# Sometimes we want to override this default behaviour and allow Rails to rescue
# exceptions and display an error page (just like when the app is running in production).
# Typical scenarios where you want to do this is when you test your error pages.
# There are two ways to allow Rails to rescue exceptions:
#
# 1) Tag your scenario (or feature) with @allow-rescue
#
# 2) Set the value below to true. Beware that doing this globally is not
# recommended as it will mask a lot of errors for you!
#
ActionController::Base.allow_rescue = false
# Remove/comment out the lines below if your app doesn't have a database.
# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
begin
DatabaseCleaner.strategy = :transaction
rescue NameError
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end
# You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios.
# See the DatabaseCleaner documentation for details. Example:
#
# Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do
# # { :except => [:widgets] } may not do what you expect here
# # as Cucumber::Rails::Database.javascript_strategy overrides
# # this setting.
# DatabaseCleaner.strategy = :truncation
# end
#
# Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do
# DatabaseCleaner.strategy = :transaction
# end
#
# Possible values are :truncation and :transaction
# The :transaction strategy is faster, but might give you threading problems.
# See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature
Cucumber::Rails::Database.javascript_strategy = :truncation
Before do
ActiveRecord::FixtureSet.reset_cache
fixtures_folder = File.join(Rails.root, 'spec', 'fixtures')
fixtures = Dir[File.join(fixtures_folder, '*.yml')].map {|f| File.basename(f, '.yml') }
ActiveRecord::FixtureSet.create_fixtures(fixtures_folder, fixtures)
end
World(FixtureAccess)
module FixtureAccess
def self.extended(base)
ActiveRecord::FixtureSet.reset_cache
fixtures_folder = File.join(Rails.root, 'spec', 'fixtures')
fixtures = Dir[File.join(fixtures_folder, '*.yml')].map {|f| File.basename(f, '.yml') }
fixtures += Dir[File.join(fixtures_folder, '*.csv')].map {|f| File.basename(f, '.csv') }
ActiveRecord::FixtureSet.create_fixtures(fixtures_folder, fixtures) # This will populate the test database tables
(class << base; self; end).class_eval do
@@fixture_cache = {}
fixtures.each do |table_name|
table_name = table_name.to_s.tr('.', '_')
define_method(table_name) do |*fixture_symbols|
@@fixture_cache[table_name] ||= {}
instances = fixture_symbols.map do |fixture_symbol|
if fix = ActiveRecord::FixtureSet.cached_fixtures(ActiveRecord::Base.connection, table_name).first.fixtures[fixture_symbol.to_s]
@@fixture_cache[table_name][fixture_symbol] ||= fix.find # find model.find's the instance
else
raise StandardError, "No fixture with name '#{fixture_symbol}' found for table '#{table_name}'"
end
end
instances.size == 1 ? instances.first : instances
end
end
end
end
end
@libbyschuknight

Copy link
Copy Markdown
Author

Thanks for Georg Duemlein

Add this files into a support folder, in features folder.

@skelz0r

skelz0r commented Dec 13, 2024

Copy link
Copy Markdown

Don't know why but with Rails 8 and SQLite, I had to change L20 with:

fix = ActiveRecord::FixtureSet.cached_fixtures(ActiveRecord::Base.connection_pool, table_name).first.fixtures[fixture_symbol.to_s]

ActiveRecord::Base.connection_pool instead of ActiveRecord::Base.connection.

I inspected ActiveRecord::FixtureSet.class_variable_get(:@@all_cached_fixtures) to find that there was 2 keys: one with connection_pool filled, and one with connection empty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment