按数据属性查找元素

the*_*lus 18 testing rspec ruby-on-rails capybara capybara-webkit

我正在改进我的测试,RSpeccapybara-webkit试图删除所有cssxpath选择器之类的

find('#edit_user > div:nth-child(7) > div > div > button').click
Run Code Online (Sandbox Code Playgroud)

我正在寻找替代它们的最佳选择.

我打算使用css class元素,但一些"专业"水豚测试人员说这不是最好的选择.

所以我的问题是:我可以data在测试中使用这些属性吗?
如果我有一个元素

<button name="button" type="submit" class="button last" data-test="edit.update">Update/button>
Run Code Online (Sandbox Code Playgroud)

我能做到吗?

find('edit.update').click
Run Code Online (Sandbox Code Playgroud)

你觉得这是个好主意吗?如果您对此主题有更多想法/信息,请随时发表评论!

Jus*_* Ko 24

要按data-*属性定位元素,您需要使用CSS选择器或XPath.

对于CSS选择器:

find('button[data-test="edit.update"]').click
Run Code Online (Sandbox Code Playgroud)

对于XPath:

find('//button[@data-test="edit.update"]').click
Run Code Online (Sandbox Code Playgroud)

它是否是一个好主意真的取决于应用程序.您想要选择唯一标识元素的内容.如果"edit.update"不是唯一的,那么它将不是一个好的选择.class如果按钮具有唯一的类,则该属性将是正常的,"按钮"和"最后"不可能是.

最好的方法是使用静态id属性,因为它们在页面中应该是唯一的,并且不太可能发生变化.该find方法还支持通过id定位元素,这意味着您不必编写CSS选择器或XPath.


Tho*_*ole 13

Justin Ko给出的答案是正确的,我只是想添加一些更先进的东西,这有助于在某些情况下测试可读性.你可以将你自己的"选择器"添加到Capybara,所以如果你真的想通过数据测试属性来选择东西(不是一个好主意,因为你真的不想为测试添加属性),你可以做很多事情

Capybara.add_selector(:dt) do
  css { |v| "*[data-test=#{v}]" }
end
Run Code Online (Sandbox Code Playgroud)

这将允许

find(:dt, 'edit.update')
Run Code Online (Sandbox Code Playgroud)

这可以使测试变得易于理解,同时还将复杂的css或路径查询限制在测试代码中的单个位置.然后,您可以定义一个方法,如

def find_by_dt(value)
 find(:dt, value)
end
Run Code Online (Sandbox Code Playgroud)

如果你更喜欢find_by_dt ...的外观来找到(:dt,...)

您还可以为自己的选择添加过滤器和描述,以获得更大的灵活性,更好的错误描述等 - 请参阅https://github.com/jnicklas/capybara/blob/master/lib/capybara/selector.rb 了解内置功能由capybara提供的选择器

  • 为什么您认为仅为测试添加属性不是一个好主意? (3认同)
  • @AndreiBotalov 有些人认为添加仅用于测试的东西是不好的做法。但是,我遇到过很多情况,其中更改一段代码会对测试代码产生涟漪效应,我最终需要花费数小时来修复测试,因为它基于某些 css 或文本。我完全同意 Kent Dodds 关于数据属性测试的文章:https://blog.kentcdodds.com/making-your-ui-tests-resilient-to-change-d37a6ee37269。简而言之 - 它使您的测试不那么脆弱。一切都与权衡有关。 (2认同)