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

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

click_link('Delete', match: :first) 

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

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

1)我认为最简单的方法是使用带有id的元素或使用xpath和click()函数的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驱动程序,您应该在Gemfile中添加gem’capybara-webkit’(您需要拥有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

更新:

您也可以从capybara源浏览此规范 ,这可以帮助您了解如何查找元素或添加选择器:

我通常使用语言环境来解决这个问题,而不是直接在我的视图中添加文本。 例如:

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

然后我可以在我的视图中访问区域设置。 这个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,这是它自己的挑战……