即使在禁用交易后,Capybara JS测试也无法访问数据库夹具

时间:2015-12-10 08:59:05

标签: javascript ruby-on-rails selenium rspec capybara

前段时间我刚刚了解到,Capybara为Javascript测试创建了一个单独的服务器和数据库连接,这意味着您在before块中设置的数据库数据在测试期间不可用。

this popular article中所述,应用程序配置如下以禁用事务性装置

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

  Capybara.configure do |config|
    config.javascript_driver = :webkit
  end

  config.before(:suite) do
    DatabaseCleaner.clean_with(:deletion)
  end

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

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

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

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

理想情况下,这应该在所有启用JS的测试中使用:deletion方法,并避免以事务方式插入数据。

我尝试了一个简单的测试,用户用他们的名字填写一个非常简单的注册表格并提交。

describe "Registration Process" do
  let(:user) { create(:user) }

  before(:each) do
    # Logs a fake user in and sets the session store so `current_user` in the Controller calls this user
    sign_in(user)
    visit registration_path
  end

  describe "Registration Form", js: true do
    before(:each) do
      fill_in :name, with: "Julio Jones"
      click_button("Submit")
    end


    it "sets the user's name" do
      expect(user.reload.name).to eq("Julio Jones")
    end
  end
end

这是提交表单时调用的控制器操作。很简单 -

class UsersController < ApplicationController
  def update
    current_user.update(name: params[:name])
  end
end

我的问题是在控制器内部,它根本无法在数据库中看到User记录

  1. 如果我在规范before块中暂停执行,我可以看到目前为止创建了1 User条记录(User.count = 1)。
  2. 如果我在正在测试的代码中暂停执行(即Controller操作),我可以看到User对象(current_user.present?true)但是我无法查看数据库中的记录(User.count = 0)
  3. 这告诉我正在正确存储和检索User模型对象,但是它使用不同的数据库连接,因为数据库表中没有存储物理支持记录。 / p>

    更奇怪的是,我可以确认它是以交易方式运行。

    ActiveRecord::Base.connection.open_transactions # => 0
    

    还有什么想法可以阻止它看到数据库记录?是否与使用:webkit作为Javascript驱动程序有关?我知道我在网上看到的大多数例子:selenium

    谢谢!

1 个答案:

答案 0 :(得分:0)

我猜如何调试capybara和服务器看到的匹配。尝试输出到视图数据库记录。这只是猜测,但我认为这样你可能会遇到水豚和服务器数据库状态的不匹配。

我实际上有同样的问题,但我使用minitest。您确定DatabaseCleaner命令以正确的顺序执行吗?在{:p>中明确尝试.start

config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :deletion
    DatabaseCleaner.start
end

在我的情况下,它已经开始使用事务策略,所以当你在没有.start的情况下即时更改策略时,DatabaseCleaner会使用旧策略。