capybara-webkit js:true rspec测试无法与数据库交互

时间:2017-04-23 22:36:57

标签: ruby-on-rails capybara rspec-rails capybara-webkit

我在许多Rails项目中将RSpec与Capybara和Capybara-webkit结合使用,它通常运行顺畅。出于某种原因,我在配置js: true功能规范时遇到了问题。他们没有正确地与数据库交互。我使用factory_girldatabase_cleaner来管理测试数据库内容。对于DatabaseCleaner.strategy = :truncation测试,我在database_cleaner.rb中有js: true但它仍然不起作用。奇怪的是,当我将ActiveRecord::Base.establish_connection放入databse_cleaner.rb时,测试工作正常。为什么?

以下是rails_helper.rb

# This file is copied to spec/ when you run 'rails generate rspec:install'
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 'spec_helper'
require 'rspec/rails'

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

ActiveRecord::Migration.maintain_test_schema!

Capybara::Webkit.configure(&:block_unknown_urls)

RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.use_transactional_fixtures = false

  config.infer_spec_type_from_file_location!

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
  # arbitrary gems may also be filtered via:
  # config.filter_gems_from_backtrace("gem name")
end

这是spec_helper.rb的重要部分:

ENV['RAILS_ENV'] ||= 'test'

ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup'
Bundler.require
require 'pry-byebug'
require 'capybara/rspec'
require 'capybara/webkit'
require 'database_cleaner'
require 'webmock/rspec'

WebMock.disable_net_connect!(allow_localhost: true)

# use `describe 'Feature', type: :feature, js: true` to use this driver
Capybara.javascript_driver = :webkit

# tests use regular (faster) driver if they don't require js
Capybara.default_driver = :rack_test

Capybara::Webkit.configure do |config|
  config.allow_unknown_urls
end

RSpec.configure do |config|
  config.after(:suite) do
    FileUtils.rm_rf(Dir["#{Rails.root}/spec/test_files/"])
  end

  config.include Capybara::DSL
...

这是database_cleaner.rb(位于spec/support):

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

当我更改它时,测试可以正确地与db交互:

config.before(:each, js: true) do
  ActiveRecord::Base.establish_connection
  DatabaseCleaner.strategy = :truncation
end

为什么呢?我不应该明确告诉它建立数据库连接。

2 个答案:

答案 0 :(得分:1)

您的问题表明您正在使用:js测试的事务,但代码显示:截断。截断是你应该用于你的js测试,所以我认为问题是一个错字。

您应该使用推荐的database_cleaner - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example - 它根据所使用的驱动程序而不是'js:true'元数据检测是否需要截断,并且还使用append_after而不仅仅after {1}},这对测试稳定性非常重要。

我也没有在你的rails_helper或spec_helper中看到require 'capybara/rails'

答案 1 :(得分:0)

当您设置js: true时,您基本上只使用Capybara,这实际上是Selenium驱动的浏览器请求。在测试过程之外运行的任何代码(如此Selenium浏览器请求)都看不到数据库夹具。

除了您正在做的事情之外,最好是在Selenium Web服务器上共享数据状态并测试代码本身。

在Rspec.config中的某个地方(可能是你的database_cleaner.rb),你要设置

config.use_transactional_fixtures = false

"使用Rspec"进行日常Rails测试有一些技巧有时需要在某些测试场景中需要在Rails 5之前共享相同的数据库连接。虽然它可能导致其他问题,如下面的评论中所指出的那样:

制作 spec / support / shared_db_connection.rb 文件并添加此内容:

class ActiveRecord::Base 
  mattr_accessor :shared_connection 
  @@shared_connection = nil

  def self.connection
    @@shared_connection || retrieve_connection
  end 
end
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection