RSpec + DatabaseCleaner + PhantomJS:数据库在js示例中被随机删除

时间:2015-09-25 13:51:19

标签: ruby-on-rails ruby rspec phantomjs rspec-rails

我的rspec功能中有一个简单的场景:

require 'spec_helper'

feature 'CLIENT views results page' do
  context 'from welcome/index form' do
    let!(:location) { FactoryGirl.create :location, name: 'town' }

    before :each do
      visit '/'
    end

    scenario 'successfully', js: true do
      expect(Location.count).to eq 1

      fill_in 'from_address', with: 'Some address'
      fill_in 'to_address', with: 'Another address'
      click_button 'Search'

      expect(page).to have_content 'Some address → Another address'
    end
  end
end

spec_helper:

require 'rubygems'

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

require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'factory_girl'
require 'database_cleaner'
require 'capybara/poltergeist'

FactoryGirl.reload

RSpec.configure do |config|
  config.use_transactional_fixtures = false

  config.infer_base_class_for_anonymous_controllers = true

  config.order = "random"
  config.tty = true
  config.mock_with :rspec
  config.filter_run focus: true
  config.run_all_when_everything_filtered = true

  config.treat_symbols_as_metadata_keys_with_true_values = true

  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

Capybara.javascript_driver = :poltergeist
Capybara.asset_host = "http://localhost:3000"
Capybara.server_port = 9887 + ENV['TEST_ENV_NUMBER'].to_i

由于事实上没有expect(Location.count).to eq 1个记录,我的方案在一些随机步骤(Location之后)失败了:

(byebug) Location.all
[]

我认为这可能是两种情况之一:

  1. 在示例完成之前,DatabaseCleaner会清理数据库
  2. 或者实际上有两个带有两个数据库的线程,其中一个(应用程序使用的那个)真的是空的
  3. 宝石版本:

    • rspec(2.14.1)
    • rspec-core(2.14.8)
    • rspec-rails(2.14.0)
    • phantomjs(1.9.7.1)
    • rails(3.2.21)
    • database_cleaner(0.9.1)

2 个答案:

答案 0 :(得分:0)

我记得也遇到过这个问题。我的数据库清理配置如下所示:

config.before(:each) do
  if Capybara.current_driver == :rack_test
    DatabaseCleaner.strategy = :transaction
  else
    DatabaseCleaner.strategy = :truncation
  end
  DatabaseCleaner.start
end

config.after do
  DatabaseCleaner.clean
end

也许它与你之前调用的块的顺序有关。因此,如果在您想要设置策略之前调用DatabaseCleaner.start,您可能会看到此类结果。

答案 1 :(得分:0)

通过迁移到

来管理解决此问题
config.use_transactional_fixtures = true

而不是使用DatabaseCleaner。一些workarounds建议使用javascript测试进行事务清理工作。我选择了这个:

(在 spec/spec_helper 开头的某处添加)

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

因为它似乎工作得更快,仍然留下一些自发的失败测试(可能不是与数据库相关的问题)。