rspec中特定上下文的一次性配置?

rspec中特定上下文的一次性配置?,rspec,Rspec,我有一些昂贵的测试设置,这些设置只对我的规范中的少数示例是必需的,如果需要,它只需要运行一次。因为它很慢,我试图避免把它放在before(:each)块中,但是before(:all)似乎不适合我的需要。我认为一个复杂的因素是,昂贵的部分必须运行后,其他一些常见的设置。(这是针对带有搜索引擎的应用程序的水豚测试。创建一些记录后,我需要索引测试数据库以获得搜索结果。)我的设置如下: feature 'some particular feature' do before(:each) do

我有一些昂贵的测试设置,这些设置只对我的规范中的少数示例是必需的,如果需要,它只需要运行一次。因为它很慢,我试图避免把它放在before(:each)块中,但是before(:all)似乎不适合我的需要。我认为一个复杂的因素是,昂贵的部分必须运行后,其他一些常见的设置。(这是针对带有搜索引擎的应用程序的水豚测试。创建一些记录后,我需要索引测试数据库以获得搜索结果。)我的设置如下:

feature 'some particular feature' do
  before(:each) do
    # a bunch of common test setup (creating records that this test will use)
  end

  describe 'simple example #1' do
    # a simple example that doesn't need the expensive setup
  end
  .
  .
  .
  describe 'simple example #N' do
    # a simple example that doesn't need the expensive setup
  end

  describe 'a more complicated example' do
    before(:all) do
      # expensive_setup that depends on the records created above
    end

    it 'does something' do ... end
    it 'does something else' do ... end
    .
    .
    .
    it 'even does this' do ... end
  end      
end
问题是,当rspec在具有
更复杂示例的上下文中运行示例时,
before(:all)
块在它所依赖的
before(:each)
块之前运行。到目前为止,我不得不将昂贵的设置放在
before(:each)
块中,而不是放在
before(:all)
块中。这意味着该示例中的每个
it
块都必须运行昂贵的设置。有更好的方法吗

更新: 我没有提到昂贵操作的结果只取决于数据库。因此,由于每个示例都使用相同的数据库设置,因此对每个示例重新使用代价高昂的操作的结果是安全的。而且,结果存在于文件系统中,因此不会在示例之间清除

我认为应该在文件系统中放置某种标记,表明结果是好的,不需要重新计算



我通过计算常见设置的摘要并将其与昂贵操作的结果一起保存,从而解决了这个问题。在执行昂贵的操作之前,请检查当前摘要是否与磁盘上的摘要匹配。如果是这样,就没有必要这样做。由于所有示例共享公共设置,因此昂贵的操作最多只运行一次。

您可以将感兴趣的部分保存在变量中,用于进行断言。以下是黑客攻击:

feature 'Aides page' do 

  context 'No active user' do
    that = nil
    before do
      if !that
        create_2_different_aids
        disable_http_service
        visit aides_path
        that = Nokogiri::HTML(page.html)
      end
    end
    after do
      enable_http_service
    end
    scenario 'Should display 2 aids NOT related to any eligibility' do
      display_2_aids_unrelated_to_eligibility(that)
    end
    scenario 'Should not display breadcrumb' do
      expect(that.css('.c-breadcrumb').size).to eq(0)
    end
  end

end

您将面临的问题是(在大多数设置中)在测试之间删除数据库记录。因此,如果昂贵的操作依赖于或创建db记录,这些记录将被销毁。在这种情况下,昂贵操作的结果存在于文件系统的一个目录中。此外,我可能需要澄清的是,代价高昂的操作的结果只取决于数据库中的记录。(它正在为数据库编制索引以进行搜索。)因此,由于每个示例中的数据库设置都是相同的,因此可以安全地重新使用前面示例中的结果。