如何保护我的Capybara测试免受任意文本更改?

时间:2014-03-20 03:15:39

标签: ruby-on-rails capybara

总的来说,我喜欢Capybara的工作原理。我发现很难相信在测试中编写用户可见文本真的是一个好主意; e.g。

click_link('Delete', match: :first)

好的,所以我用这样的测试编写我的应用程序,然后我的设计师通过,或者品牌/营销人员看到"删除"因为我们没有"删除"事情,我们"删除"他们(或者其他 - 点是,它是随意的)。因此,他们通过对我的应用程序中的按钮和链接的内容进行任意更改,现在即使应用程序正常工作,我的所有测试都会被破坏。他们并不是真正的编码人员,所以他们不知道如何处理我的测试,实际上,我认为我的测试不应该关心他们选择改变的文本。如果我需要将整个shebang翻译成其他语言,他们不应该非常关心。

解决这个问题的理智方法是什么?我以为我可以为每个可测试元素添加一个CSS类并寻找它,但这似乎可能与设计师发生冲突。我可以为我的测试添加其他无意义的元数据来提示吗?或者我是以错误的方式看待这个?

2 个答案:

答案 0 :(得分:2)

1)我认为最简单的方法是使用带有id的元素或使用xpath和find()函数的find方法:

以下是一个例子:

feature 'Shall check devise authorization' do

  scenario "shall authorize User with correct email and password" do
    user = User.find(1)
    visit new_user_session_path
    fill_in "user[email]", with: user.email
    fill_in "user[password]", with: user.password
      # click_button "Sign in"
    find('input#sign_in_button').click()
      # find("//input[@id='sign_in_button']").click()
    has_selector? 'input#created_at_first'
  end

end

这里click_button"登录"与

相同
find('input#sign_in_button').click() 
[id of element] 

也与

相同
find("//input[@id='sign_in_button']").click()
[xpath]

选择你想要的任何东西。

如果您想按类和ID选择元素,这是解决方案:

find('input#sign_in_button.btn.btn-primary.btn-success').click()
find("//input[@class='btn btn-primary btn-success'][@id='sign_in_button']").click()

检查页面capybara#finding也很有帮助。有很多有用的信息。

2)另一种选择是使用capybara#scripting

但它有点困难,因为你需要配置你的Capybara驱动程序来测试JS。

要配置您的Capybara驱动程序,您应该添加gem' capybara-webkit'在你的Gemfile中(你需要有libqtwebkit-dev)。

sudo apt-get install libqtwebkit-dev
bundle install 

然后在spec_helper.rb中输入以下内容:

Capybara.current_driver = :webkit
Capybara.run_server = true #Whether start server when testing
#Capybara.server_port = 3000
#Capybara.default_selector = :css #:xpath #default selector , you can change to :css
Capybara.default_wait_time = 5 #When we testing AJAX, we can set a default wait time
Capybara.ignore_hidden_elements = false #Ignore hidden elements when testing, make helpful when you hide or show elements using javascript
Capybara.javascript_driver = :webkit

以下规范将正常运行:

# -*- encoding : utf-8 -*-
require_relative '../spec_helper'

feature 'Shall check devise authorization' do

  scenario "shall authorize User with correct email and password", js: true do
    user = User.find(1)
    visit new_user_session_path
    fill_in "user[email]", with: user.email
    fill_in "user[password]", with: user.password

    page.execute_script("$('#sign_in_button').click()")

    has_selector? 'input#created_at_first'
  end

end

capybara-webkit驱动程序用于真正的无头测试。它使用QtWebKit启动渲染引擎进程。它也可以执行JavaScript。它比Selenium等驱动程序快得多,因为它不加载整个浏览器

有关详细信息,请访问test-javascript-with-capybara-webkit

<强>更新

您还可以浏览this spec from capybara source,它可以帮助您了解如何查找元素或添加选择器:

答案 1 :(得分:0)

我通常使用区域设置而不是直接在视图中添加文本来解决此问题。例如:

# config/locales/en.yml
en:
  buttons:
    delete: &delete "Remove"
  my_model:
    index:
      delete: *delete
    show:
      delete: *delete

然后我可以在我的视图中访问区域设置。这个erb代码将呈现一个按钮,用文本&#34;删除&#34;:

删除我的记录
<!-- app/views/my_models/show.html.erb -->
<%= link_to t(".delete"), my_model_path(@my_model), method: :delete %>

我可以在我的规范中使用翻译帮助程序来查找按钮。要做到这一点,首先我需要包括翻译助手:

# spec/rails_helper.rb
RSpec.configure do |config|
  config.include ActionView::Helpers::TranslationHelper
  # ...
end

# spec/features/my_model_spec.rb
RSpec.feature "MyModel", type: :feature  do
  scenario "clicking a delete button" do
    click_link(t("buttons.delete"), match: :first)
  end
end

现在唯一的诀窍是教我的设计师如何使用i18n,这是它自己的挑战......