RSpec - 如何嵌套之前:all和before:每个块交互?

时间:2014-03-18 18:43:51

标签: ruby rspec

我使用RSpec和Selenium / Capybara / SitePrism遇到了一些Web UI Automation的问题。它与代码中出现的before :allbefore :each子句的组合有关,尤其是在我的spec_helper文件中。

到目前为止,我一直在针对一个spec文件运行rspec。每个spec文件都需要一个spec_helper文件,其中包括以下内容:

spec_helper.rb:
  RSpec.configure do |config|
    config.before(:all) do
      # 1) Code to configure WebDriver and launch Browser is here
    end
  end

由于各种原因,规范文件本身包含自己的before块。其中大多数包含以下内容:

test_a_spec.rb:
  describe "Page A" do
    before :all do
      # 2) Log in to web site, maybe load the test page in question
    end
    it "does this thing" do
      # 3) Test this thing
    end
    it "does that thing" do
      # 4) Test that thing
    end
  end

只要我针对单个spec文件运行RSpec,这就可以正常工作。当我尝试标记我的一些示例然后针对整个spec文件夹运行时,我遇到了问题。 before :all中的spec_helper.rb块并没有像我想象的那样在每个文件前面添加,而是在开头运行一次。第一个之后的所有规范文件都期望spec_helper启动一个干净的浏览器并自己完成登录部分,但是浏览器不干净并且已经登录,所以这并不好。

before :all中的spec_helper.rb更改为before :each似乎是一种自然的解决方案,所以我做了,突然我的测试立即失败,并声称rack-test requires a rack application, but none was given错误。这发生在我的一些测试中但不是全部,并且通过消除过程我意识到只有测试有自己的before :all块失败。看来,规范文件中的before :all取代了before :each文件中的spec_helper。因此它在启动浏览器之前尝试登录。

这让我感到烦恼。我非常烦恼。我有两种假设:

  • 我认为before :eachbefore :all平起平坐,实际上从某种意义上来说,它更像before :all加上更多。 before :all取代before :each的想法对我来说似乎很奇怪。

  • 我假设所有这些before块都以合理的方式嵌套。也就是说,before :all块应该在其下面的所有内容之前触发一次,这意味着在可能包含before :each块的before :all块的每次迭代中触发。另外,如果before :each包含一些代码,然后下面的描述语句包含before :all,则before :each代码仍应在before :all代码之前触发。也许它确实这样做了,我现在还不确定。

问题:

1)我的spec_helper文件实际产生了什么样的行为?例如,如果我采取相同的行为并将其放入其中一个spec文件中,那会是什么样子?带有浏览器启动代码的before :each是否会在某种隐式describe块中包围spec文件中的所有代码? before :each是否插入到最外层的描述块中,因此必须与spec文件的before :all块竞争?

2)我可以通过放弃测试中的所有before :all块来“解决”这个问题,但我喜欢事物的灵活性,因为这是UI自动化,速度是一个因素,我不喜欢我真的想打开一个新的浏览器并登录每个描述,尽管我知道这对于保持每个测试与其他测试分开是理想的。我是否必须/想要这样做?

谢谢!

2 个答案:

答案 0 :(得分:2)

要解决https://stackoverflow.com/a/22489263/1008891未涵盖的问题部分,require方法将不会重新加载之前已加载的任何文件,如https://stackoverflow.com/a/22489263/1008891中所述。这与load方法形成对比,requires方法就像文件内容的“复制/粘贴”一样,无论在何处使用。

我不是说如果您将所有loads更改为{{1}},那么您将获得与运行单个文件相同的结果,因为可能存在影响行为的其他全局状态你看到了。

答案 1 :(得分:0)

RSpec文档(http://rspec.info/documentation/3.3/rspec-core/RSpec/Core/Hooks.html#before-instance_method)提供了一些非常有用的信息,关于块之前的交互方式以及它们的运行顺序,但是它们建议避免之前(:context)[aka before(:all)]

仅供参考,注意后块是以相反的顺序运行的,在块之前是。