Rspecのbefore,afterの順番

### 順番
```rb
before :suite
  before :context
  before :example
  after  :example
  after  :context
  after  :suite
```
### 意味
```rb
  before(:example) # run before each example
  before(:context) # run one time only, before all of the examples in a group

  after(:example) # run after each example 
  after(:context) # run one time only, after all of the examples in a group　一回だけ、グループのすべてのexampleが終わったら実行される
```
#### 実行する前にraiseされる
>### Failure in before(:context) block
>Given a file named “beforecontextspec.rb” with:
```rb
RSpec.describe "an error in before(:context)" do
  before(:context) do
    raise "oops"
  end

  it "fails this example" do
  end

  it "fails this example, too" do
  end

  after(:context) do
    puts "after context ran"
  end

  describe "nested group" do
    it "fails this third example" do
    end

    it "fails this fourth example" do
    end

    describe "yet another level deep" do
      it "fails this last example" do
      end
    end
  end
end
```
#### exampleを後から失敗させる
>### Failure in after(:context) block
>Given a file named “aftercontextspec.rb” with:
```rb
RSpec.describe "an error in after(:context)" do
  after(:context) do
    raise StandardError.new("Boom!")
  end

  it "passes this example" do
  end

  it "passes this example, too" do
  end
end
```
#### exampleの失敗はフックに影響を与えない
>### A failure in an example does not affect hooks
>Given a file named “failureinexample_spec.rb” with:
```rb
RSpec.describe "a failing example does not affect hooks" do
  before(:context) { puts "before context runs" }
  before(:example) { puts "before example runs" }
  after(:example) { puts "after example runs" }
  after(:context) { puts "after context runs" }

  it "fails the example but runs the hooks" do
    raise "An Error"
  end
end
```
```
before context runs
before example runs
after example runs

RuntimeError: An Error

  0) a failing example does not affect hooks fails the example but runs the hooks
     Failure/Error: raise "An Error"

     RuntimeError:
       An Error
     # ./spec/models/user_spec.rb:21:in `block (2 levels) in <top (required)>'
after context runs
```
#### コンフィギュレーションにおいてブロックの前後を定義する
>### Define before and after blocks in configuration
>Given a file named “beforesinconfiguration_spec.rb” with:
```rb
require "rspec/expectations"

RSpec.configure do |config|
  config.before(:example) do
    @before_example = "before example"
    puts "ok1"
  end
  config.before(:context) do
    @before_context = "before context"
    puts "ok2"
  end
end

RSpec.describe "stuff in before blocks" do
  describe "with :context" do
    it "should be available in the example" do
      expect(@before_context).to eq("before context")
    end
  end
  describe "with :example" do
    it "should be available in the example" do
      expect(@before_example).to eq("before example")
    end
  end
end
```
```
ok2
ok1
ok1
2 examples, 0 failures, 2 passed
```
#### before/afterブロックは順番に実行する　context,example関係なく前、後で呼び出される
>### before/after blocks are run in order
>Given a file named “ensureblockorder_spec.rb” with:
```rb
require "rspec/expectations"

RSpec.describe "before and after callbacks" do
  before(:context) do
    puts "before context"
  end

  before(:example) do
    puts "before example"
  end

  before do
    puts "also before example but by default"
  end

  after(:example) do
    puts "after example"
  end

  after do
    puts "also after example but by default"
  end

  after(:context) do
    puts "after context"
  end

  it "gets run in order" do

  end
end
```
```
before context
before example
also before example but by default
also after example but by default
after example
after context
1 example, 0 failures, 1 passed
```
* exampleが実行される前だからafterよりもafter(:example)の方が後から出力される

#### コンフィギュレーションで定義されたbefore/afterブロックは順番(ルールにおいて）に実行される
>### before/after blocks defined in configuration are run in order
>Given a file named “configuration_spec.rb” with:
```rb
require "rspec/expectations"

RSpec.configure do |config|
  config.before(:suite) do
    puts "before suite"
  end

  config.before(:context) do
    puts "before context"
  end

  config.before(:example) do
    puts "before example"
  end

  config.after(:example) do
    puts "after example"
  end

  config.after(:context) do
    puts "after context"
  end

  config.after(:suite) do
    puts "after suite"
  end
end

RSpec.describe "ignore" do
  example "ignore" do
  end
end
```
```
before suite
before context
before example
after example
after context
after suite
1 example, 0 failures, 1 passed
```
```
before suite
before context
before example
after example
after context
after suite
1 example, 0 failures, 1 passed
```
#### bdfore/after contextブロックは一度だけ実行される 
>### before/after context blocks are run once
>Given a file named “beforeandaftercontextspec.rb” with:
```rb
RSpec.describe "before and after callbacks" do
  before(:context) do
    puts "outer before context"
  end

  example "in outer group" do
  end

  after(:context) do
    puts "outer after context"
  end

  describe "nested group" do
    before(:context) do
      puts "inner before context"
    end

    example "in nested group" do
    end

    after(:context) do
      puts "inner after context"
    end
  end

end
```
```
outer before context
inner before context
inner after context
outer after context
2 examples, 0 failures, 2 passed
```
* ブロックにおいての順番を守る
#### 入れ子のexamplesは外側のbefore(:context)で設定された状態へアクセスできる　
>### Nested examples have access to state set in outer before(:context)
>Given a file named “beforecontextspec.rb” with:
```rb
RSpec.describe "something" do
  before :context do
    @value = 123
  end

  describe "nested" do
    it "access state set in before(:context)" do
      expect(@value).to eq(123)
    end

    describe "nested more deeply" do
      it "access state set in before(:context)" do
        expect(@value).to eq(123)
      end
    end
  end

  describe "nested in parallel" do
    it "access state set in before(:context)" do
      expect(@value).to eq(123)
    end
  end
end
```
```
3 examples, 0 failures, 3 passed
```
* beforeで変数の設定もできる

#### before/after contextブロックは状態へアクセスできる
>### before/after context blocks have access to state
>Given a file named “beforeandaftercontextspec.rb” with:
```rb
RSpec.describe "before and after callbacks" do
  before(:context) do
    @outer_state = "set in outer before context"
  end

  example "in outer group" do
    expect(@outer_state).to eq("set in outer before context")
    puts 1
  end

  describe "nested group" do
    before(:context) do
      @inner_state = "set in inner before context"
    end

    example "in nested group" do
      expect(@outer_state).to eq("set in outer before context")
      expect(@inner_state).to eq("set in inner before context")
      puts 2
    end

    after(:context) do
      expect(@inner_state).to eq("set in inner before context")
      puts 3
    end
  end

  after(:context) do
    expect(@outer_state).to eq("set in outer before context")
    put 4
  end
end
```
```
1
2
3
4
2 examples, 0 failures, 2 passed

```
#### before(:example)の例外は失敗として捕捉され、記録される
>### Exception in before(:example) is captured and reported as failure
>Given a file named “errorinbeforeexamplespec.rb” with:
```rb
RSpec.describe "error in before(:example)" do
  before(:example) do
    raise "this error"
  end

  it "is reported as failure" do
  end
end
```
```
RuntimeError: this error

  0) error in before(:example) is reported as failure
     Failure/Error: raise "this error"

     RuntimeError:
       this error
     # ./spec/models/user_spec.rb:16:in `block (2 levels) in <top (required)>'
1 example, 1 failure, 0 passed
```
https://rspec.info/features/3-13/rspec-core/hooks/before-and-after-hooks/

#### 実験
```rb
RSpec.describe "before and after callbacks" do
  before(:context) do
    @outer_state = "set in outer before context"
  end

  example "in outer group" do
    expect(@outer_state).to eq("set in outer before context")
    puts 1
  end

  describe "nested group" do
    before(:context) do
      @inner_state = "set in inner before context"
    end
    before(:suite) do
      @inner_state = "set in inner before context!!!!!!"
    end

    example "in nested group" do
      expect(@outer_state).to eq("set in outer before context")
      expect(@inner_state).to eq("set in inner before context")
      puts 2
    end

  end

  after(:context) do
    expect(@outer_state).to eq("set in outer before context")
    puts 4
  end
end
```
```
`before(:suite)` hooks are only supported on the RSpec configuration object. This `before(:suite)` hook, registered on an example group, will be ignored.
```
before(:suite）はRspecコンフィグレーションオブジェクトでのみサポートされる
登録されたbefore(:suite）は無視される

コンフィギュレーションで定義されたbefore/afterブロックは順番(ルールにおいて）に実行されるから
コンフィグレーションの意味を志らくてはいけないな