このソリューションを使用して、javascript テスト中のデータベースの問題を回避しています。
スイートを最初に実行すると、テストは正常に実行され、すべて合格します。
スイート全体をもう一度実行しても、合格します。
しかし、個別のスペック ファイルを実行してからスイート (または他の個別のテスト) を実行しようとすると、次のエラーが発生します。
An error occurred in an after hook
ActiveRecord::StatementInvalid: ArgumentError: prepare called on a closed database: rollback transaction
occurred at /home/steveq/.rvm/gems/ruby-1.9.3-p194@rails32/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `initialize'
1) Signing up with valid information
Failure/Error: visit "/sign_up"
ActiveRecord::StatementInvalid:
ArgumentError: prepare called on a closed database: PRAGMA table_info("users")
# ./app/controllers/registrations_controller.rb:3:in `new'
# ./app/controllers/registrations_controller.rb:3:in `new'
# ./spec/features/sign_up_feature_spec.rb:5:in `block (2 levels) in <top (required)>'
ガードをリロードすると、テストは再びパスします。
ここで何が起こっているのか、または考えられる解決策について何か洞察を持っている人はいますか? 考えられるすべてのバリエーションを試しました。ここに、試したことを示すspec_helperファイルがあります(バリエーションはコメントアウトされています。現在のコード-カピバラページで提案されているもの-現在使用しているものです) .
require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
# 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|
#Make it so Selenium (out of thread) tests can work with transactional fixtures
#REF http://opinionated-programmer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/#comment-220
# ActiveRecord::ConnectionAdapters::ConnectionPool.class_eval do
# def current_connection_id
# # Thread.current.object_id
# Thread.main.object_id
# end
# end
# FactoryGirl short syntax
config.include FactoryGirl::Syntax::Methods
config.use_transactional_fixtures = true
# set up for use with :js => true.
# See http://stackoverflow.com/questions/8178120/capybara-with-js-true-causes-test-to-fail for more info
# config.before :suite do
# if Capybara.current_driver == :rack_test
# DatabaseCleaner.strategy = :transaction
# else
# DatabaseCleaner.strategy = :truncation
# end
# DatabaseCleaner.start
# end
# config.after do
# DatabaseCleaner.clean
# end
# standard RSPEC config
# config.before(:suite) :truncation
# else
# :transaction
# end do
# DatabaseCleaner.strategy = if example.metadata[:js]
# :truncation
# else
# :transaction
# end
# DatabaseCleaner.clean_with(:truncation)
# end
# config.before(:each) do
# DatabaseCleaner.start
# end
# config.after(:each) do
# DatabaseCleaner.clean
# end
# config.before(:each) do
# DatabaseCleaner.strategy = if example.metadata[:js]
# :truncation
# else
# :transaction
# end
# DatabaseCleaner.start
# end
# config.after(:each) do
# DatabaseCleaner.clean
# end
# 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
# 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.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
config.include MailerMacros
config.include LoginMacros
config.before(:each) { reset_email }
config.include Devise::TestHelpers, :type => :controller
config.extend LoginMacros, :type => :controller
end
end
Spork.each_run do
# allows capybara JS tests to run in separate thread
class ActiveRecord::Base
mattr_accessor :shared_connection
@@shared_connection = nil
def self.connection
@@shared_connection || retrieve_connection
end
end
# Forces all threads to share the same connection. This works on
# Capybara because it starts the web server in a thread.
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
# This code will be run each time you run your specs.
load "#{Rails.root}/config/routes.rb"
FactoryGirl.reload
# reload all the models
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
load model
end
end