【问题标题】:Capybara and before(:all) in rspecrspec 中的 Capybara 和 before(:all)
【发布时间】:2013-01-16 18:08:17
【问题描述】:

这是我的完整规格:

require 'spec_helper'

describe "Idea page", js: true do

  subject { page }

  before(:all) do
    create(:idea)
    visit root_path
    click_link "Log In"
  end

  context "Single idea" do
    before do
      page.find(:xpath, '//*[@id="accordion"]/div/div[1]/a').click
    end

    it { should have_selector('a',text:'Claim') }
    it "should have a button for reporting the idea"
    it "should have a button for opening all links"

    describe "Claiming" do
      before do
        click_link "Claim"
      end
      it {should have_selector('a', text:'Claimed')}
    end

  end
end

没有(:all)(即,当它在第一个块中只是before 时),浏览器打开,单击登录链接,转到右侧页面,然后单击该链接。好的。

但是在尝试单击第二个链接(“Claim”)之前,它会再次执行此操作,这既费时又容易出错。所以我尝试用before(:all) 解决这个问题。

但是现在,它只是弹出打开 Firefox,等待片刻,然后再次关闭它,什么也不做。测试失败说:

Failures:

  1) Idea page Single idea 
     Failure/Error: page.find(:xpath, '//*[@id="accordion"]/div/div[1]/a').click
     Capybara::ElementNotFound:
       Unable to find xpath "//*[@id=\"accordion\"]/div/div[1]/a"
     # ./spec/features/ideas_spec.rb:15:in `block (3 levels) in <top (required)>'

  2) Idea page Single idea Claiming 
     Failure/Error: page.find(:xpath, '//*[@id="accordion"]/div/div[1]/a').click
     Capybara::ElementNotFound:
       Unable to find xpath "//*[@id=\"accordion\"]/div/div[1]/a"
     # ./spec/features/ideas_spec.rb:15:in `block (3 levels) in <top (required)>'

显然,因为浏览器页面是空白的。

我错过了什么?谢谢。

编辑:也许有一些基本的我不明白。使用before(:each),这是测试尝试做的事情:

1) 登录 webapp,确保有一个“Claim”按钮。

2) 再次登录到 webapp,再次打开手风琴,现在点击“Claim”按钮,看看会发生什么。

所以每一步的开始都是完全相同的,浏览器一遍又一遍地做同样的事情。应该是这样吗?

如果是这样,为什么我这样做时会出错?具体来说,before(:each) 我明白了:

Failures:

  1) Idea page Single idea Claiming 
     Failure/Error: it {should have_selector('a', text:'Claimed')}
     Selenium::WebDriver::Error::UnhandledAlertError:
       Modal dialog present
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/command_processor.js:10287:in `nsCommandProcessor.execute'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/driver_component.js:7328:in `Dispatcher.executeAs/<'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/driver_component.js:7488:in `Resource.handle'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/driver_component.js:7435:in `Dispatcher.dispatch'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/driver_component.js:10119:in `WebDriverServer/<.handle'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1935:in `unknown'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:2261:in `ServerHandler.handleResponse'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1168:in `Connection.process'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1616:in `RequestReader._handleResponse'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1464:in `RequestReader._processBody'
     # [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1333:in `RequestReader.onInputStreamReady'
     # ./spec/features/ideas_spec.rb:26:in `block (4 levels) in <top (required)>'

即使我看到浏览器单击按钮,将其变为“已声明”,并且没有显示模式对话框。

编辑 2: 我的立场是正确的!毕竟那里有 模态对话框!我修复了 JS 以停止显示它,现在测试通过了。我仍然认为框架必须在每一步都从头开始重复整个序列是很奇怪的(似乎是在浪费工作),但无论如何。谢谢!

【问题讨论】:

  • 如果您使用shared_context,您可以将登录过程放入其中,并让您更清楚您在做什么include_context "After signing in"...而且它减少了打字!
  • @iain 又来救援了! :) 谢谢!一定会检查出来的。

标签: ruby-on-rails rspec capybara bdd


【解决方案1】:

这是因为测试数据,包括 capybara 会话数据(例如登录状态)和 create(:idea) 创建的模型在规格之间被清除了。

您想使用before(:each) 而不是:all,即使它更耗时。

【讨论】:

  • 一些澄清,当@ezuk 刚刚before,那是在做before(:each)。它们是等价的。
  • 不,before(:each) 已经是默认设置,而这正是我不想要的。在询问之前我已经阅读了文档。 :)
  • 如果您运行before(:all) 并执行create(:idea),则该模型将在您的规格之间被破坏。 Capybara会销毁它的session数据等你很不想要before(:all)
  • 换句话说,要使用before(:all),您必须在测试之间维护状态,并且每个测试框架都会在每一步都与您抗争。
  • 感谢@DanielEvans;所以我想我试图解决错误的事情。编辑了问题以解释为什么我试图避免 before(:each) 以及使用它时会发生什么。
猜你喜欢
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-27
  • 1970-01-01
  • 2023-04-08
  • 2011-02-03
相关资源
最近更新 更多