Ruby RSpec-嵌套的before:all和before:each块如何交互?
我在使用RSpec和Selenium/Capybara/SitePrism实现一些Web用户界面自动化时遇到了一个问题。它与代码中出现的Ruby RSpec-嵌套的before:all和before:each块如何交互?,ruby,rspec,Ruby,Rspec,我在使用RSpec和Selenium/Capybara/SitePrism实现一些Web用户界面自动化时遇到了一个问题。它与代码中出现的before:all和before:each子句的组合有关,尤其是在我的spec\u helper文件中 到目前为止,我一直在一次针对一个规范文件运行rspec。每个等级库文件都需要一个spec\u helper文件,其中包括以下内容: spec_helper.rb: RSpec.configure do |config| config.before
before:all
和before:each
子句的组合有关,尤其是在我的spec\u helper
文件中
到目前为止,我一直在一次针对一个规范文件运行rspec。每个等级库文件都需要一个spec\u helper
文件,其中包括以下内容:
spec_helper.rb:
RSpec.configure do |config|
config.before(:all) do
# 1) Code to configure WebDriver and launch Browser is here
end
end
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_helper.rb:
RSpec.configure do |config|
config.before(:all) do
# 1) Code to configure WebDriver and launch Browser is here
end
end
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
只要我对单个规范文件运行RSpec,这就可以正常工作。当我尝试标记一些示例,然后运行整个spec文件夹时,我遇到了一个问题。spec\u helper.rb
中的before:all
块并没有像我想的那样在每个文件前加前缀,而是在开始时运行一次。第一次之后的所有规范文件都希望spec\u helper
启动一个干净的浏览器,并自己进行部分登录,但是浏览器不干净,已经登录,所以这不是很好
将spec\u helper.rb
中的before:all
更改为before:each
似乎是自然的解决方案,我这样做了,突然我的测试立即失败,错误称机架测试需要机架应用程序,但没有提供任何。这发生在我的一些测试中,但不是全部,通过消除过程,我意识到只有测试之前有自己的:所有的块都失败了。spec文件中的before:all
似乎取代了spec\u帮助文件中的before:each
。因此,它试图在启动浏览器之前登录
这让我很烦恼。我非常恼火。我假设了两件事:
- 我假设
before:each
与before:all
处于同等地位,事实上,从某种意义上说,它就像一个before:all
加上更多。在我看来,before:all
将取代before:each
的想法很奇怪
- 我假设所有这些
之前的块都以合理的方式嵌套。也就是说,一个before:all
块应该在它下面的所有东西之前触发一次,这意味着在before:each
块的每次迭代中触发可能包含before:all
块的每个块。此外,如果before:each
包含一些代码,然后下面的描述语句在before:all
之前有一个before:each
代码,则before:each
代码仍应在before:all
代码之前触发。也许它真的做到了,我只是现在不确定
问题:
1) 我的spec\u helper
文件实际产生了什么样的行为?例如,如果我采取同样的行为,并将其放入某个规范文件本身,那会是什么样子?before:each
和浏览器启动代码是否会以某种隐式描述块的形式围绕spec文件中的所有代码?before:each
是否插入到最外层的descripe块中,因此必须与spec文件的before:all
块竞争
2) 我可以通过放弃以前所有的:我测试中的所有块来“解决”这个问题,但我喜欢事情的灵活性,因为这是UI自动化,速度是一个因素,我真的不想打开一个新的浏览器并为每个描述登录,尽管我知道这将是保持每个测试与其他测试分离的理想方法。我必须/想这样做吗
谢谢 要解决问题中尚未涉及的部分,如中所述,require
方法不会重新加载以前加载的任何文件。这与load
方法形成对比,该方法在使用文件内容的任何地方都像“复制/粘贴”一样
我并不是说,如果您将所有的requires
更改为loads
,您将获得与运行单个文件相同的结果,因为可能存在其他全局状态影响您看到的行为。RSpec文档()提供了一些关于before块如何交互以及它们的运行顺序的非常有用的信息,但是它们建议避免before(:context)[aka before(:all)]
仅供参考,请注意后块的运行顺序与前块的运行顺序相反。我觉得处理require
vsload
可能不是正确的选择,我也不确定它是否会改变行为。我原以为spec\u helper
对不同的spec文件的作用会有所不同,但显然没有。spec\u helper
中的配置显然将应用于rspec
认为是运行一部分的示例和示例组,而不管它们位于哪个文件中。谢谢,我同意更改为load
可能不是正确的选择,而且可能不会改变任何东西。其他答案是否不足以解决您的其他问题?简言之,您可以在配置中使用before(:suite)
进行“每次RSpec调用一次”操作,在配置中使用“before(:all)`进行“每次顶级示例一次”示例操作。这些操作不会“竞争”“在示例级别调用前使用,
;它们是相互补充的。我得出的结论是,最好只使用before:each
,避免before:all
,就像它是魔鬼一样。我相信我在写这个问题时产生困惑的主要原因与spe的方式有关