这是我的spec_helper.rb
:
RSpec.configure do |config|
config.before(:each) do
login(email, password)
visit root_url
end
end
我需要的所有(20+)测试除了一个。
有没有办法避免单一测试执行before hook
?
答案 0 :(得分:18)
您可以向不需要登录的测试添加元数据,然后在before
挂钩中评估该元数据。
例如,在同一文件中进行两次测试。一个人需要登录,一个人不需要登录。
# foo_spec.rb
describe Foo do
describe "#bar" do
it "needs to log in" do
expect(1).to eq 1
end
end
describe "#baz" do
it "needs to not log in", :logged_out do
expect(1).to eq 1
end
end
end
因此我们在it
块中添加了元数据。接下来,我们配置before
挂钩来评估示例的元数据。
config.before(:each) do |test|
login(email, password) unless test.metadata[:logged_out]
visit root_url
end
现在,每个测试都会visit root_url
,但只有未标记为:logged_out
的测试会调用login
。
RSpec调用这些基于元数据的钩子过滤器。您可以了解更多关于他们的信息here。
答案 1 :(得分:3)
将这种代码放入规范帮助器中似乎有点奇怪。您拥有的功能规格是什么?没有单元测试?即使它是前者,也要将该代码复制到需要它的单个规范中。如果它们全部在同一个文件中,您可以使用上下文来防止重复。
RSpec.describe 'something' do
context 'specs with login' do
before do
login(email, password)
visit root_url
end
it { ... }
end
context 'specs without login' do
it { ... }
end
end
spec_helper.rb中的全局rspec配置用于其他事情。对每个规范都有意义的事情。例如,清理数据库。
config.before :each do
DatabaseCleaner.clean
end
答案 2 :(得分:1)
无论是1还是10都不需要它,遗憾的是它并没有改变spec_helper.rb中的任何代码将适用于所有代码的事实。上面答案中的另一个选项是在钩子代码之前创建一个spec_login.rb文件,然后在需要它的测试文件中需要它。
规格/ spec_login.rb
RSpec.configure do |config|
config.before(:each) do
login(email, password)
visit root_url
end
end
spec / 1_spec.rb(需要登录)
require 'spec_login'
describe 'BlahBlah' do
end
spec / 2_spec.rb(无登录)
describe 'BlahBlah' do
end
答案 3 :(得分:0)
另一个选择是继续使用spec_helper.rb
中的配置,当测试在我不需要的规范中开始时,执行
describe "test" do
it "1" do
logout
visit(another_page)
.
.
.
end
end
答案 4 :(得分:0)
您也可以在spec_helper's config.before(:each) block
内进行检查
基于test.metadata[:described_class] or [:example_group]
。
它具有有关当前上下文的大量信息,因此从块内部进行过滤而不是单独更改规格可能会更直接一些。