0

我不得不说我对 Ruby 和 RSpec 都是新手。无论如何,我完成了一个 RSpec 脚本,但在重构后它失败了。这是原始工作版本:

describe Site do
  browser = Watir::Browser.new :ie
  site    = Site.new(browser, "http://localhost:8080/site")

  it "can navigate to any page at the site" do
    site.pages_names.each do |page_name|
      site.goto(page_name)
      site.actual_page.name.should eq page_name
    end
  end
  browser.close
end

这是修改后的版本 - 我想报告测试期间访问的所有页面:

describe Site do
  browser = Watir::Browser.new :ie
  site    = Site.new(browser, "http://localhost:8080/site")

  site.pages_names.each do |page_name|
    it "can navigate to #{page_name}" do
      site.goto(page_name)
      site.actual_page.name.should eq page_name
    end
  end
  browser.close
end

后一种情况的问题是,在与“it”方法关联的代码块中,站点被评估为 nil。但是当我这样做时:

...
s = site
it "can navigate to #{page_name}" do
  s.goto(page_name)
  s.actual_page.name.should eq page_name
end
...

nil 问题消失了,但测试失败,原因是“浏览器已关闭”显然我缺少一些非常基本的 Ruby 知识——因为浏览器引用在修改后的脚本中无法正常工作。我哪里做错了?应该应用什么重构来完成这项工作?谢谢你的帮助!

4

2 回答 2

0

我使用 Site 和 Watir 的假类复制了上面的代码。它工作得很好。那么我唯一的结论是问题必须出在上述任何一个类中。我注意到 Site 实例只需要访问您的第一个工作版本中的一个页面,但必须访问非工作版本中的多个页面。那里可能存在涉及实例内部发生突变的问题。

看看这是否有所作为:

describe Site do
    uri = "http://localhost:8080/site" 
    browser = Watir::Browser.new :ie 
    page_names = Site.new(browser, uri).page_names 

    before(:each) { @site = Site.new(browser, uri) }
    after(:all) { browser.close }

    pages_names.each do |page_name|
      it "can navigate to #{page_name}" do
        @site.goto(page_name)
        @site.actual_page.name.should eq page_name
      end
    end  
  end
于 2012-12-30T22:52:01.690 回答
0

重要的是要了解 RSpec 和许多 ruby​​ 程序一样,有两个运行时阶段:

  1. 在第一阶段,RSpec 加载您的每个规范文件,并执行每个describecontext块。在此阶段,您的代码的执行定义了您的示例、钩子等。但您的示例和钩子在此阶段不会执行。
  2. 一旦 RSpec 完成加载规范文件(并且所有示例都已定义),它就会执行它们。

所以......将您的示例精简为更简单的形式,这就是您所拥有的:

describe Site do
  browser = Watir::Browser.new :ie

  it 'does something with the browser' do
    # do something with the browser
  end

  browser.close
end

虽然在视觉上看起来浏览器实例已被实例化,然后在示例中使用,然后关闭,但实际情况如下:

  1. 浏览器实例被实例化
  2. 该示例已定义(但未运行)
  3. 浏览器已关闭
  4. (稍后,在定义了所有示例之后...)示例运行

正如 O.Powell 的回答所示,您可以在after(:all)挂钩中关闭浏览器以延迟关闭,直到该示例组中的所有示例都运行后。也就是说,我会质疑您在示例定义时是否真的需要浏览器实例。通常,当示例在运行时需要它们时,而不是在示例定义阶段,您最好懒惰地创建资源(例如浏览器实例)。

于 2012-12-31T05:19:33.977 回答