前段时间我刚刚了解到,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
记录
before
块中暂停执行,我可以看到目前为止创建了1 User
条记录(User.count
= 1)。User
对象(current_user.present?
是true
)但是我无法查看数据库中的记录(User.count
= 0)这告诉我正在正确存储和检索User
模型对象,但是它使用不同的数据库连接,因为数据库表中没有存储物理支持记录。 / p>
更奇怪的是,我可以确认它是不以交易方式运行。
ActiveRecord::Base.connection.open_transactions # => 0
还有什么想法可以阻止它看到数据库记录?是否与使用:webkit
作为Javascript驱动程序有关?我知道我在网上看到的大多数例子:selenium
谢谢!
答案 0 :(得分:0)
我猜如何调试capybara和服务器看到的匹配。尝试输出到视图数据库记录。这只是猜测,但我认为这样你可能会遇到水豚和服务器数据库状态的不匹配。
我实际上有同样的问题,但我使用minitest。您确定DatabaseCleaner命令以正确的顺序执行吗?在{:p>中明确尝试.start
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :deletion
DatabaseCleaner.start
end
在我的情况下,它已经开始使用事务策略,所以当你在没有.start
的情况下即时更改策略时,DatabaseCleaner会使用旧策略。