我使用RSpec和Selenium / Capybara / SitePrism遇到了一些Web UI Automation的问题。它与代码中出现的before :all
和before :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 :each
与before :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自动化,速度是一个因素,我不喜欢我真的想打开一个新的浏览器并登录每个描述,尽管我知道这对于保持每个测试与其他测试分开是理想的。我是否必须/想要这样做?
谢谢!
答案 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)]
仅供参考,注意后块是以相反的顺序运行的,在块之前是。