Rspec 水豚网络工具包不';我似乎没有足够快地提交表格

Rspec 水豚网络工具包不';我似乎没有足够快地提交表格,rspec,capybara,capybara-webkit,Rspec,Capybara,Capybara Webkit,我正在使用Capybara测试一个基本表单-当用户填写并提交表单时,它应该创建一个新的用户记录 it "creates a new user" do visit some_random_path # Fill In Form fill_in("name", with: "foo bar") fill_in("email", with: "foo.bar@example.com") expect do click_button("Submit") end.to

我正在使用Capybara测试一个基本表单-当用户填写并提交表单时,它应该创建一个新的
用户
记录

it "creates a new user" do
  visit some_random_path

  # Fill In Form
  fill_in("name", with: "foo bar")
  fill_in("email", with: "foo.bar@example.com")

  expect do
    click_button("Submit")
  end.to change { User.count }.by(1)
end
expect
块抛出错误,因为它没有看到
用户。计数增加1。但是我注意到如果我做了类似的事情

click_button("Submit") && sleep(0.1)
expect do
  click_button("Submit")
  expect(page).to have_text("New User Created") # whatever appears on screen to indicate successful creation of the user
end.to change { User.count }.by(1)
它工作得很好

因此,RSpec似乎试图检查得太快,即在运行Capybara的浏览器有机会实际提交表单并提交针对DB的结果之前

我没有使用任何JavaScript,只是一个普通的老
:webkit
规范

有没有想过为什么会发生这种情况

下面是我的水豚配置。我有一个多租户应用程序(我正在使用,不管它有什么意义),所以我使用
localhost
lvh.me
作为应用程序的主机,如下所述,但我无法想象这会干扰上述内容

Capybara.configure do |config|
  config.ignore_hidden_elements = true
  Capybara.default_driver = :webkit
  config.javascript_driver = :webkit
end

Capybara::Webkit.configure do |config|
  config.block_unknown_urls
  config.allow_url("lvh.me")
end

RSpec.configure do |config|
  config.before(:suite) do
    Capybara.always_include_port = true
    # The default is to treat each spec as single tennat, in which case
    # we want to hit localhost. Hitting the Capbyara default of www.example.com
    # causes the apartment setup to try and parse the `www` as a subdomain
    Capybara.app_host = "http://localhost"
  end

  config.before(:each, multi_tenant: true) do
    # For multi-tenant specs, use "lvh.me"
    Capybara.app_host = "http://lvh.me"
  end
end
谢谢

当将其中一个“real browser”驱动程序与Capybara一起使用时(除了rack_测试外,几乎所有驱动程序都是如此),当click方法返回时,通过单击按钮触发的任何操作都不能保证完成。这意味着您需要在继续之前检查页面上是否存在表明操作已完成的可见更改。对你来说,这意味着

click_button("Submit") && sleep(0.1)
expect do
  click_button("Submit")
  expect(page).to have_text("New User Created") # whatever appears on screen to indicate successful creation of the user
end.to change { User.count }.by(1)

请注意,在编写功能测试时,直接进行DB检查通常被认为是一种不好的代码味道,您确实应该只检查用户索引页上的新用户显示、确认出现成功消息或类似的内容,而不是检查
user.count

修复效果很好!我最终使用了
expect(current\u path)。将eq(current\u path)
作为一种黑客手段,让它等待
current\u path可用。另外,出于个人考虑,感谢您对水豚的持续支持-这是一个非常有用的工具,我知道需要花费时间/精力来维护,因此非常感谢。@user2490003-Hmm--我不确定
期望(当前路径)是什么。eq(当前路径)
实际会做什么--这种行为可能与驱动程序高度相关。如果你知道你期望的路径是什么
expect(第页)。拥有当前路径(expected\u path)
会更好(使用
eq
匹配器与
current\u path
/
当前url
从来都不是一个好主意)