【问题标题】:Testing RESTful API with Cucumber in a front end less application在前端少的应用程序中使用 Cucumber 测试 RESTful API
【发布时间】:2026-02-10 07:55:02
【问题描述】:

您好,我的应用中没有任何前端。我愿意只发布一个可供不同客户端使用的 RESTful API。任何指示我应该如何继续用黄瓜测试它?控制器中的每个操作仅生成 XML 提要。有什么指点或建议吗?

【问题讨论】:

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


    【解决方案1】:

    webrat 的visit 函数接受http_method 作为第二个参数。您还可以像以下黄瓜规则一样测试您的 api:

    When /^I restfully delete (?:|the )user "([^\"]*)"$/ do |login|
      visit(path_to("user \"#{login}\" page"), :delete)
    end
    

    【讨论】:

      【解决方案2】:

      我认为 Webrat 不仅仅是您所需要的。 对于 XML 提要测试,您不需要像 Webrat 这样的浏览器模拟器,它会在您确实没有任何 HTML 页面时加载页面并分析所有标记(链接、表单等)。

      您宁愿需要像 Curl (http://curl.haxx.se) 或 Curb(在 ruby​​forge 上,它们是 Curl 的 ruby​​ 绑定)或 Patron(在 ruby​​forge 上)之类的东西。

      这些库可以根据您的喜好制作请求标头(例如设置 Content-Type,在 GET PUT POST DELETE HEAD 等中进行选择)并获取响应,并在需要时可能遵循 302 重定向。

      返回的响应可以转换为 XML 对象,并且可以使用 Ruby 可用的 XML 解析器来测试输出。此外,您可以编写 XMLMapping 类(在 ruby​​forge 上)将 XML 输出转换为 Ruby 对象并测试它们的属性等。恕我直言,这更干净。

      【讨论】:

      • 好的,这真的很有用。我正在使用 Curb 和 XMLMapping 来测试我的应用程序。除了一些底层的脏代码外,它工作得很好。但我想我的测试中可能会有一些脏代码。
      【解决方案3】:

      jayzes 分享了他的黄瓜测试步骤示例,使用 Rack::Test::Methods、JSONpath、Nokogiri 等为 json/xml API 编写测试,您可能想参考并为自己的步骤创建更多。

      https://github.com/jayzes/cucumber-api-steps

      【讨论】:

        【解决方案4】:

        设置好 RESTful 路由后,您应该能够使用 Webrat 访问不同的路由。然后,您可以测试每个路由是否返回符合您期望的 XML。

        这是一篇博客文章,描述了如何在 RSpec 中测试 XML 输出: Testing XML output

        Webrat 是一个无头浏览器,这仅仅意味着您可以模拟一个浏览器,而无需在您的开发机器上打开像 FireFox 这样的真实浏览器。这意味着您可以在定义的步骤中简单地键入“访问'users/'”之类的内容并模拟用户访问您的应用程序。

        最后,Pragmatic book on RSpec(仍处于测试阶段)是关于如何结合使用 Cucumber、Webrat 和 RSpec 并通过 BDD 推动应用程序开发的绝佳资源。

        【讨论】:

        • 谢谢 :) 我的应用程序没有任何前端,这意味着如果我没有可用于销毁特定资源的“删除”按钮。现在 AFAIK Webrat 不允许您使用特定的 HTTP 动词(GET、POST 等)请求特定的 url。我应该如何处理这个问题?我可以使用 Rspec 轻松做到这一点,但它不再支持“用户故事”。这是一个不同的问题。 :)
        • 您可以通过访问特定的 URL 来模拟 GET 方法。为了模拟 PUT 或 DELETE 动词,您应该能够在访问链接之前使用 set_hidden_​​field "_method"、"PUT" 或 set_hidden_​​field "_method"、"DELETE"。不过我还没试过。
        • webrat 的 set_hidden_​​field 文档。它说“它验证当前页面上是否存在隐藏字段并将值设置为给定参数。”由于我的应用程序没有任何前端,因此我没有任何 hidden_​​field 或 form_field 或可与之交互的按钮。我想我需要一种方法来请求具有不同 HTTP 动词的不同 Rest URL。类似于 bitlasoft.com/tools/rest_client/">this</a> 但可以自动化。
        • “RESTful 路由”用词不当。听起来像 RPC。
        【解决方案5】:

        我试图这样做,但遇到了 restful_authentication 的一个主要问题(使用 AASM,它似乎是 restful_auth 的内部模型之一),并找到了登录的解决方案:

        Given /^I am logged in with a new account$/ do  
          login = "test"
          @current_user = User.new(
             :login => login,
             :password => 'generic',
             :password_confirmation => 'generic',
             :email => "#{login}@example.com",
             :state => "active"
           )
           @current_user.save
           x = User.find_by_login(login)
           x.state = "active"
           x.save!
        
           visit "/login" 
           fill_in("login", :with => login) 
           fill_in("password", :with => 'generic') 
           click_button
           response.body.should =~ /Logged in successfully/m
        end
        

        将其模块化以便更清晰的测试语料库,这是为了演示我发现的概念。

        【讨论】: