【问题标题】:RSpec + DatabaseCleaner + PhantomJS: database get randomly erased during example with jsRSpec + DatabaseCleaner + PhantomJS:在使用 js 的示例中,数据库被随机擦除
【发布时间】:2015-09-25 13:51:18
【问题描述】:

我的 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. 或者实际上有两个线程有​​两个数据库,其中一个(应用程序使用的那个)真的是空的

宝石版本:

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

【问题讨论】:

  • 您确定您的工厂会创建没有任何验证错误的便笺吗?
  • 是的,这个例子更进一步expect(Location.count).to eq 1
  • (byebug) Location.all → [#<Location id: 1, name: "town">]
  • 尝试将此位置创建从“让!”移动到您的场景块。之后发生了什么?
  • @violarium,试过这个:pastie.org/private/6zbow8laznt26iuzyyvw 相同的行为

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


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    设法通过迁移到解决此问题

    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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-15
      • 2020-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多