【问题标题】:Why would binding.pry cause Rspec Selenium test to fail?为什么 binding.pry 会导致 Rspec Selenium 测试失败?
【发布时间】:2016-06-02 19:59:15
【问题描述】:

我看到了一些非常有趣的行为。考虑一个基本的 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 比较陌生,但这是第一次没有帮助,导致我浪费了数小时的时间。我在文档中没有看到任何有助于澄清的内容。有其他人在这里有经验吗?

【问题讨论】:

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


    【解决方案1】:

    当使用支持 JS 的驱动程序测试应用程序时,应用程序在与测试不同的线程中运行。这意味着当您将 binding.pry 添加到控制器代码时,它会暂停,但测试线程可能会继续,完成/失败测试,​​然后运行数据库清理器来清理您的对象。如果您在撬动会话中相对较快,您会找到您的对象(在 sleep(5) 时间范围内) - 否则它们可能会被清理并消失。它还告诉您错误发生在后挂钩中,但您没有在代码中显示任何后挂钩,仅在之前?

    注意:在 Capybara 的测试中使用 sleep() 通常是不受欢迎的,因为这意味着您的测试将花费比必要更长的时间。相反,您应该检查页面上指示操作已完成的视觉变化 - 类似于

    expect(page).to have_text('Order updated') 
    

    expect(page).to have_current_path('/success')
    

    等等。取决于您的应用的具体功能或显示更新成功的方式

    【讨论】:

      猜你喜欢
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-23
      相关资源
      最近更新 更多