【问题标题】:Easy way to test nested model forms with Cucumber?用 Cucumber 测试嵌套模型表单的简单方法?
【发布时间】:2011-08-13 06:46:30
【问题描述】:

我在 Hospitals 表单中有一个部门的嵌套模型。代码 sn-p 如下所示:

    <%= f.simple_fields_for :hospital do |h| %>
    .
    .
    .       
       <%= h.simple_fields_for :departments do |builder| %>
              <%= render "department_fields", :f => builder %>
            <% end %>
.
.
    <% end %>

_department_fields 部分如下所示:

<div class="fields">
    <%= f.input :name %>
    <%= link_to_remove_fields "remove", f %>
    </span>
</div>

因此,表单底部有一个地方供用户输入最多三个部门名称。

我正在使用 Rails 3、Cucumber、Capybara 和 Selenium 进行集成测试。

在 Cucumber 中测试此表单时,是否有一种简单的方法可以填写重复字段?

理想情况下,我希望能够像这样编写我的功能:

And I fill in the first "Name" with "Cardiology"
And I fill in the second "Name" with "Radiology"

有什么方法可以在 Cucumber/Capybara 中轻松近似此值吗?有人已经想出了解决这个问题的一些步骤吗?

【问题讨论】:

    标签: ruby-on-rails cucumber nested-forms capybara


    【解决方案1】:

    Capybara 可以通过使用 inside 来处理这个问题。例如:

    And I fill in "Name" with "Radiology" within "fields"
    

    例如,如果您在两个表单区域周围都有 id 为“hospital_fields”和“department_fields”的 div,您可以执行以下操作来区分您填写的字段:

    And I fill in "Name" with "Cardiology" within "hospital_fields"
    And I fill in "Name" with "Radiology" within "department_fields"
    

    您还可以通过使用文本字段 id 而不是字段标签名称来更具体。例如,如果第一个文本字段的 id 为“hospital_name”,第二个文本字段的 id 为“hospital_department_name”,您可以执行以下操作:

    And I fill in "hospital_name" with "Cardiology"
    And I fill in "hospital_deparment_name" with "Radiology"
    

    更新:您还可以添加自定义黄瓜步骤以使用编号输入:

    When /^(?:|I )fill in the (\d+)(?:st|nd|rd|th) "([^"]*)" with "([^"]*)"$/ do |num, name, value|
      find(:xpath, ".//form/input[@name='#{name}'][#{num}]").set(value)
    end
    
    And I fill in the 1st "name" with "Cardiology"
    And I fill in the 2nd "name" with "Radiology"
    

    UPDATE:要与标签匹配,请使用以下表达式:

    find(:xpath, ".//input[@id=//label[contains(.,'#{name}')]/@for][#{num}]").set(value)
    

    【讨论】:

    • 感谢您的回答,但我可能没有充分解释问题。您会看到“名称”字段在“department_fields”中至少重复 4 次;这样,用户最多可以为医院输入 4 个科室。所以指定“在'department_fields'内”很有用,但不能解决我的问题。通过 id 指定也是有问题的,因为用户可以选择添加超过 4 个部门,此时,测试套件似乎附加了一个随机的 id 编号,所以我无法完全测试这种方式。此外,id 真的很丑。
    • @Kevin,我也更新了我的答案以应对这种情况。
    • 感谢潘的代码。我收到一个错误 Unable to find './/form/input[@name='Name'][2]' (Capybara::ElementNotFound),但我想我明白了它的要点。我的页面结构中的某些东西一定是把它扔掉了。
    • 确保名称没有大写,因为@name 指的是 HTML 属性。您还可以使用 //input 而不是 //form/input 使 XPATH 表达式更通用。
    • 我意识到了这个问题 - 我想搜索标签而不是名称(doh!)我尝试了以下方法,我认为它很接近,但不太有效:find(:xpath, "。 //输入[@id=//label[contains(.,'#{name}')][#{num}]/@for]").set(value).我可以找到第一个出现的位置,但找不到后面的。
    【解决方案2】:

    看来潘​​会帮你找到问题的答案。

    不过,我想在这里加两分钱。正如很多人推荐的那样,包括 Dan North [1]、Ben Mabey [2]、Jonas Nicklas [3] 甚至 Aslask Hellesøy 都建议你删除 web_steps.rb [4],你应该尽量不要写黄瓜场景带有显示实现细节的步骤。

    When I fill in "Name" with "Cardiology"
    

    这是关于根据标签或 ID 或其他任何内容填充 HTML 表单输入...这是实现。

    我想你可以采取以下步骤:

    When I create a department called "Cardiology"
    And I create a department called "Radiology"
    

    Dan North 甚至建议只有一个“事件”[5](一个“时间”步骤):

    When I create departments called "Cardiology" and "Radiology"
    

    然后,所有表单/html 处理都封装在一个步骤定义中。当然,您可以应用上面建议的 XPath 表达式 Pan。

    【讨论】:

    • 感谢您的建议!我没有考虑为每个场景替换或自定义 web_steps.rb 的想法,但我可以看到这将如何提高我的功能的可读性。我需要考虑一下。
    • 我很高兴它有帮助!我真的认为编写“好”功能是必不可少的。特别是如果您将它们用作真正的交流工具。
    • 这是可靠的建议。请记住,除非您与利益相关者共享 Cucumber 测试,否则use RSpec instead 的工作效率要高得多。否则,您至少可以尝试使用 Capybara Test Helpers 之类的工具将复杂性封装在步骤中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多