【问题标题】:before(:each) for all tests except onebefore(:each) 用于除一个之外的所有测试
【发布时间】:2015-12-22 14:10:07
【问题描述】:

这是我spec_helper.rb的一部分:

RSpec.configure do |config|

 config.before(:each) do
  login(email, password)
  visit root_url
 end

end

我在所有 (20 多个) 测试中都需要,除了一个。

有没有办法避免单一测试来执行before hook

【问题讨论】:

    标签: ruby-on-rails ruby testing rspec capybara


    【解决方案1】:

    您可以将元数据添加到不需要登录的测试中,然后在 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

    【讨论】:

      【解决方案2】:

      将这种代码放入规范助手中似乎有点奇怪。功能规格就是您的全部?没有单元测试?即使是前者,也可以将该代码复制到需要它的各个规范中。如果它们都在同一个文件中,您可以使用上下文来防止某些重复。

      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
      

      【讨论】:

      • 我有很多规格(1_spec.rb、2_spec.rb、3_spec.rb 等),这就是为什么我将登录和访问放在我的 spec_helper 中,因为我需要它们在所有测试。除了一个......
      • @fabersky:换句话说,您在 each 规范中不需要它们?因此不能使用 spec_helper。
      • 如果我将 before do 与一些不同的操作放在我不需要登录和访问的规范中,将 rspec 执行之前在我的 spec_helper 或在我正在运行规范?
      • 我有 22 个规格,其中 21 个需要它们
      • @fabersky:它会同时运行。
      【解决方案3】:

      无论是 1 还是 10 都不需要它,遗憾的是它不会改变 spec_helper.rb 中的任何代码都将适用于所有人的事实。上面答案的另一个选择是在钩子代码之前创建一个 spec_login.rb 文件,然后在需要它的测试文件中使用它。

      spec/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
      

      【讨论】:

      • 这个spec_login.rb 的东西恐怕不行。它进行全局更改(安装全局 before 钩子,此文件运行后不会清除)。
      【解决方案4】:

      您也可以在spec_helper's config.before(:each) block 内进行检查 基于test.metadata[:described_class] or [:example_group]

      它包含有关当前上下文的大量信息,因此从块内部进行过滤可能会更直接一些,而不是单独更改规范。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-09
        • 2013-01-10
        • 1970-01-01
        • 1970-01-01
        • 2015-08-11
        相关资源
        最近更新 更多