为什么 binding.pry 会导致 Rspec Selenium 测试失败?
Why would binding.pry cause Rspec Selenium test to fail?
我看到了一些非常有趣的行为。考虑基本 rails 设置,用户可以创建新对象 Order
或编辑现有对象。有一个控制器操作可以同时执行这两项操作(正如您在下面的代码中看到的那样)。
我正在 运行 进行功能测试,以检查 EDIT 是否正常工作。该测试使用 Selenium 并正确设置我的 DatabaseCleaner 策略以截断并覆盖默认事务功能。因此,以下测试代码将通过:
# Controller code
def create_or_update
...
if order_params[:id]
@order = Order.find(order_params[:id].to_i)
@order.assign_attributes(modified_order_params)
else
@order = Order.new(modified_order_params)
end
if @order.save
redirect_to "success"
else
render params[:page]
end
...
end
# RSpec code
describe "set up order", js: true, driver: :selenium, type: :feature do
before do
@order = Order.create({...})
visit "/edit/#{@order.id}"
end
describe "when user submits changes" do
before do
find(".order[data-id='1'] [name='specification']").set("red color")
find(".submit-changes").click
sleep(5)
end
it "should save changes" do
order = Order.last
order.specification.should == "red color"
end
end
end
同样,上面的代码通过得很好,我可以通过查看生成的页面来手动确认它确实通过了。
但是,如果我像这样将 binding.pry
注入到控制器代码中:
# Controller code
def create_or_update
...
binding.pry
if order_params[:id]
@order = Order.find(order_params[:id].to_i)
@order.assign_attributes(modified_order_params)
else
@order = Order.new(modified_order_params)
end
if @order.save
redirect_to "success"
else
render params[:page]
end
...
end
测试突然失败。为什么?因为这个:
An error occurred in an after hook
ActiveRecord::RecordNotFound: Couldn't find Order with 'id'=1 occurred at /Users/jamesdong/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.1/lib/active_record/relation/finder_methods.rb:320:in `raise_record_not_found_exception!'
在 binding.pry
环境中,我得到了不同的结果。有时会发生这种情况:
Order.count
=> 1
Order.last.inspect
=> "#<Order id: 1 ...
其他时候会发生这种情况:
Order.count
=> 0
请注意,即使可以找到订单,测试也会失败,并出现相同的错误,即无法找到 ID 为 1 的订单。
我对使用 binding.pry
还比较陌生,但这是第一次它没有帮助,让我浪费了几个小时的时间。我在文档中没有看到任何有助于澄清的内容。还有其他人有这方面的经验吗?
使用支持 JS 的驱动程序测试应用时,应用 运行 处于与测试不同的线程中。这意味着当您将 binding.pry 添加到控制器代码时,它会暂停但测试线程可能会继续,finishes/fails 测试然后数据库清理器 运行 清理您的对象。如果你在你的 pry 会话中相对较快,你会找到你的对象(在 sleep(5) 时间范围内) - 否则它们可能会被清理干净并消失。它还告诉您错误发生在 after 钩子中,但是您没有在代码中显示任何 after 钩子,只有之前???
注意:在 Capybara 的测试中使用 sleep()
通常不受欢迎,因为这意味着您的测试将花费比必要时间更长的时间。相反,您应该检查页面上的视觉变化,指示操作已完成 - 类似于
expect(page).to have_text('Order updated')
或
expect(page).to have_current_path('/success')
等具体取决于您的应用的功能或显示更新成功的方式
我看到了一些非常有趣的行为。考虑基本 rails 设置,用户可以创建新对象 Order
或编辑现有对象。有一个控制器操作可以同时执行这两项操作(正如您在下面的代码中看到的那样)。
我正在 运行 进行功能测试,以检查 EDIT 是否正常工作。该测试使用 Selenium 并正确设置我的 DatabaseCleaner 策略以截断并覆盖默认事务功能。因此,以下测试代码将通过:
# Controller code
def create_or_update
...
if order_params[:id]
@order = Order.find(order_params[:id].to_i)
@order.assign_attributes(modified_order_params)
else
@order = Order.new(modified_order_params)
end
if @order.save
redirect_to "success"
else
render params[:page]
end
...
end
# RSpec code
describe "set up order", js: true, driver: :selenium, type: :feature do
before do
@order = Order.create({...})
visit "/edit/#{@order.id}"
end
describe "when user submits changes" do
before do
find(".order[data-id='1'] [name='specification']").set("red color")
find(".submit-changes").click
sleep(5)
end
it "should save changes" do
order = Order.last
order.specification.should == "red color"
end
end
end
同样,上面的代码通过得很好,我可以通过查看生成的页面来手动确认它确实通过了。
但是,如果我像这样将 binding.pry
注入到控制器代码中:
# Controller code
def create_or_update
...
binding.pry
if order_params[:id]
@order = Order.find(order_params[:id].to_i)
@order.assign_attributes(modified_order_params)
else
@order = Order.new(modified_order_params)
end
if @order.save
redirect_to "success"
else
render params[:page]
end
...
end
测试突然失败。为什么?因为这个:
An error occurred in an after hook
ActiveRecord::RecordNotFound: Couldn't find Order with 'id'=1 occurred at /Users/jamesdong/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.1/lib/active_record/relation/finder_methods.rb:320:in `raise_record_not_found_exception!'
在 binding.pry
环境中,我得到了不同的结果。有时会发生这种情况:
Order.count
=> 1
Order.last.inspect
=> "#<Order id: 1 ...
其他时候会发生这种情况:
Order.count
=> 0
请注意,即使可以找到订单,测试也会失败,并出现相同的错误,即无法找到 ID 为 1 的订单。
我对使用 binding.pry
还比较陌生,但这是第一次它没有帮助,让我浪费了几个小时的时间。我在文档中没有看到任何有助于澄清的内容。还有其他人有这方面的经验吗?
使用支持 JS 的驱动程序测试应用时,应用 运行 处于与测试不同的线程中。这意味着当您将 binding.pry 添加到控制器代码时,它会暂停但测试线程可能会继续,finishes/fails 测试然后数据库清理器 运行 清理您的对象。如果你在你的 pry 会话中相对较快,你会找到你的对象(在 sleep(5) 时间范围内) - 否则它们可能会被清理干净并消失。它还告诉您错误发生在 after 钩子中,但是您没有在代码中显示任何 after 钩子,只有之前???
注意:在 Capybara 的测试中使用 sleep()
通常不受欢迎,因为这意味着您的测试将花费比必要时间更长的时间。相反,您应该检查页面上的视觉变化,指示操作已完成 - 类似于
expect(page).to have_text('Order updated')
或
expect(page).to have_current_path('/success')
等具体取决于您的应用的功能或显示更新成功的方式