【问题标题】:How to make Capybara do a DELETE request in a Cucumber feature?如何让 Capybara 在 Cucumber 功能中执行 DELETE 请求?
【发布时间】:2012-02-10 13:55:50
【问题描述】:

我正在使用 Cucumber 和 Capybara。我需要发出一个 HTTP DELETE 请求。以前使用webrat的特性,所以简单的声明一下

visit "/comment/" + comment_id, :delete

工作,但现在我正在使用 Capybara。

发出GET 请求的方法很简单:

get 'path'

并做一个发布请求:

page.driver.post 'path'

但是如何模拟DELETE 请求呢?

我发现 Capybara 使用的驱动程序是 Capybara::RackTest::Driver,如果有帮助的话。

我也试过了:

Capybara.current_session.driver.delete "/comments/" + comment_id

但这不起作用。

【问题讨论】:

  • 您的网页上没有会触发删除的链接或按钮吗? Cucumber 特性应该是一个全栈验收测试。您的功能步骤应该带您完成应用程序的愉快流程。您应该点击链接并按下按钮并填写数据等,然后您可以通过这样做来触发删除。
  • 当我编写新测试时,您的建议将是这样做的首选方式,但目前我正在从 webrat 迁移到 capybara。我不想通过重写来修改这 30 个左右的测试,我想先让它们使用 capybara 工作,然后可能会根据需要在以后重写。
  • 真的很奇怪,因为这些方法包含在 RackTest 驱动程序中:github.com/jnicklas/capybara/blob/master/lib/capybara/rack_test/…

标签: ruby-on-rails cucumber integration-testing capybara


【解决方案1】:
page.driver.submit :delete, "/comments/#{comment_id}", {}

文档地址:http://rubydoc.info/gems/capybara/1.1.2/Capybara/RackTest/Browser:submit

【讨论】:

  • 值得一提的是,该方法是 RackTest 驱动程序独有的,因此在 Selenium 或 Capybara-webkit 中不起作用。
  • 这适用于 capybara-webkit(我怀疑它也适用于 selenium)。
  • +1 感谢上帝。在测试“快乐路径”时,这当然不是您需要的技术,但这让我更容易测试访问控制并确保我的之前过滤器正常工作。
【解决方案2】:

如果您使用的驱动程序不支持自定义 HTTP 请求(例如 Capybara-webkit,请参阅 closed issue 和当前的 driver),您可以暂时切换到 RackTest 驱动程序来提交您的请求。

例如:

# Submit an HTTP delete request, using rack_test driver
def http_delete path
  current_driver = Capybara.current_driver
  Capybara.current_driver = :rack_test
  page.driver.submit :delete, path, {}
  Capybara.current_driver = current_driver
end

【讨论】:

  • 这个解决方案要好得多。谁知道你以后会用什么驱动。
  • 这个解决方案有一个(潜在的)大问题:它不会保留来自先前请求的任何会话或 cookie 信息。因此,例如,如果您需要作为经过身份验证的用户发出 DELETE 请求,则此代码可能不起作用(除非您已经在使用 :rack_test 驱动程序)。有关保留会话信息的方法,请参阅 my proposed solution
【解决方案3】:
page.driver.delete("/comments/#{comment_id}")

使用delete 可以正常工作。无需为此使用较低级别的submit 方法。

PS:使用 capybara-webkit 1.6.0 和 capybara 2.4.4 测试

【讨论】:

    【解决方案4】:

    如果您需要一个保留会话信息的解决方案(例如,如果您需要作为经过身份验证的用户发出您的 DELETE 请求),并且这将与 :rack_test 一起使用驱动程序 :webkit 驱动程序(假设您的应用程序中有 jQuery),试试这样的:

    def manual_http_request(method, path)
      if Capybara.current_driver == :rack_test
        page.driver.submit method, path, {}
      else
        page.execute_script("$.ajax({url: '#{path}', data: {}, type: '#{method}'});")
        # Wait for the request to finish executing...
        Timeout.timeout(10) { loop until page.evaluate_script('jQuery.active').zero? }
      end
    end
    

    我怀疑这也适用于:selenium 驱动程序,但尚未对其进行测试。也许其他人可以插话。

    【讨论】:

    • 这很好!我不需要 selenium 和 chromedriver 的超时
    【解决方案5】:

    这适用于硒。假设您在调用它的任何页面上都有一个注销按钮/链接

    代替:

    visit '/logout'
    

    做:

    def logout_user
      logout_link = page.first('#my_css_selector')
      logout_link.click if logout_link
    end
    
    #... elsewhere in a step
    logout_user
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      • 1970-01-01
      • 2011-10-08
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多