ruby RSpec在钩子之前、之后和周围运行的顺序是什么?

wwwo4jvm  于 2023-08-04  发布在  Ruby
关注(0)|答案(3)|浏览(116)

当我面对some issue时,我决定检查beforeafter钩子的执行顺序。这就是我所做的:

require "spec_helper"

describe "The order:" do

  before(:all) {
    puts "before_all"
  }

  after(:all) {
    puts "after_all"
  }

  before(:each) {
    puts "before_each"
  }

  after(:each) {
    puts "after_each"
  }

  describe "DESC A" do
    before {
      puts "A_before"
    }
    it "A_it_1" do      
      expect(1).to eq(1)
    end
    it "A_it_2" do
      expect(1).to eq(1)
    end
  end

  describe "DESC B" do
    before {
      puts "B_before"
    }
    it "B_it_1" do      
      expect(1).to eq(1)
    end
    it "B_it_2" do
      expect(1).to eq(1)
    end
  end  
end

字符串
我得到了什么:

The order:

before_all

  DESC A
before_each
A_before
after_each
    A_it_1
before_each
A_before
after_each
    A_it_2
  DESC B
before_each
B_before
after_each
    B_it_1
before_each
B_before
after_each
    B_it_2

after_all


这是怎么回事?为什么after_eachA_it_1之前运行?

更新:

添加around(:each)更有趣:

around(:each) do |example|
    puts "around_in"
    example.run
    puts "around_out"
  end


结果:

The order:
before_all
  DESC A
around_in
before_each
A_before
after_each
around_out
    A_it_1
around_in
before_each
A_before
after_each
around_out
    A_it_2
  DESC B
around_in
before_each
B_before
after_each
around_out
    B_it_1
around_in
before_each
B_before
after_each
around_out
    B_it_2
after_all

zfciruhq

zfciruhq1#

您的输出和www.example.com上记录的官方输出relishapp.com是正确的。实际上,rspec需要在每个示例之后运行after(:each),因为after(:each)中的异常会导致示例失败。在rspec可以在输出中显示示例之前,它需要知道它是绿色还是红色,这意味着在示例的描述出现在输出中之前,需要运行after(:eaches)。
然而,如果你在实际的例子中放入一个puts语句,你会看到before(:each)出现在它之前,然后运行例子代码(包括puts),然后是after(:each),就像你所期望的那样,最后,例子的描述被输出到屏幕上。
和你一样,我也很困惑,直到我意识到rspec打印出示例的标签与它实际做的事情不一致--只有为示例运行了所有before(:all)、before(:each)es和after(:each)es之后,标签才会被打印出来。
注意:after(:all)在示例标签被打印出来之后才运行,因为它们不会影响测试的结果(after(:all)钩子中发生异常时会生成一个警告,但这不会使测试变红)。

yvt65v4c

yvt65v4c2#

RSpec's documentation for before and after hooks指定它们运行的顺序。但是,RSpec's documentation for around hooks没有指定它们运行的顺序。
本规范测试aroundbeforeafter:all:each以及示例的执行顺序。当我使用rspec(-core)2.14.8运行它时,它们按照您期望的顺序执行:

describe "order in which rspec around/before/after hooks run" do
  before :all do
    defined?($previous_hook).should be_false # this hook runs first
    $previous_hook = "before :all"
  end
  
  around :each do |example|
    $previous_hook.should == "before :all"
    $previous_hook = "around :each 1"
    example.run
    $previous_hook.should == "after :each"
    $previous_hook = "around :each 2"
  end

  before :each do
    $previous_hook.should == "around :each 1"
    $previous_hook = "before :each"
  end
  
  it "should not raise an exception or print anything" do
    $previous_hook.should == "before :each"
    $previous_hook = "example"
  end
  
  after :each do
    $previous_hook.should == "example"
    $previous_hook = "after :each"
  end
  
  after :all do
    # rspec ignores assertion failures and any other exceptions raised here, so all we can do is puts.
    # $previous_hook is a global because if it's an instance variable it is "before :all" at this point.
    warn "Previous hook was #{$previous_hook}, NOT around :each 2 as expected" unless $previous_hook == "around :each 2"
  end

end

字符串
注意一些可能令人惊讶的事情:

  • self:all:each块中是不同的,所以我需要使用全局变量而不是示例变量。
  • after :all(但不是before :all)会吃异常。
  • 看看所有这些地方.should工作!你通常不会想在那里使用它。
h7wcgrx3

h7wcgrx33#

这一点上面已经回答过了,只是再补充一个简单的回答方式。
要查看钩子运行的顺序,还必须在“it”中添加“puts”语句
所以呢

describe "The order:" do

  before(:all) {
    puts "before_all"
  }

  after(:all) {
    puts "after_all"
  }

  before(:each) {
    puts "before_each"
  }

  after(:each) {
    puts "after_each"
  }

  describe "DESC A" do
    before {
      puts "A_before"
    }
    it "A_it_1" do      
      # expect(1).to eq(1)       <<<<---- Change Here
      puts "Inside the test"
    end
  end
end

字符串

相关问题