🐘

RSpec の before の順番を調べてみた

2022/09/22に公開

はじめに

RSpec の before の実行される順番、よくわからなくないですか?

調べてみると letlet!before など、別のブロック間の実行順序などは出てくるんですが、 context が複雑にネストしていて、かつそれぞれに before ブロックが存在する場合、どういった順番で実行されるのか、検索して調べてもあまり出てこないですよね。順番に依存しない before ブロックを書ければ良いですが、必ずしもそうじゃありません。

今回の記事では、before が様々なブロックに散らばっている場合、各テスト前にどの順番で実行されるか調べてみました。

RSpec とは

Rubyのテスティングフレームワークです。
https://rspec.info/

before とは

RSpecの before には実は様々な種類があります。
単に before とだけ書いた場合は、before(:example) や、 before(:each) と書いた場合と同義になります。

before(:example) before(:each) とは

it もしくは example の前に実行される命令を指定するブロックです。

順番をドキュメントから調べる

RSpec-Coreのドキュメントに Order という項があり、ここに実行される順番が記載されています。

以下引用

before(:suite)    # Declared in RSpec.configure.
before(:context)  # Declared in RSpec.configure.
before(:context)  # Declared in a parent group.
before(:context)  # Declared in the current group.
before(:example)  # Declared in RSpec.configure.
before(:example)  # Declared in a parent group.
before(:example)  # Declared in the current group.

before(:example) について着目すると、

  1. RSpec.configure 内で宣言された before(:example)
  2. 親グループで宣言された before(:example)
  3. 現在のグループで宣言された before(:example)

が、順番に itexample の前に実行されるみたいですね。

実際に動かして確かめてみましょう。

実際に実行してみる

環境

❯ ruby --version
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin21]

❯ bundle exec rspec --version
RSpec 3.11
  - rspec-core 3.11.0
  - rspec-expectations 3.11.1
  - rspec-mocks 3.11.1
  - rspec-support 3.11.1

実行するコード

spec/before_test_spec.rb
RSpec.configure do |config|
  config.before do
    puts 'before in configure'
  end
end

describe do
  before do
    puts 'before in describe'
  end

  context 'A' do
    before do
      puts 'before in context A'
    end

    context 'B' do
      before do
        puts 'before in context B'
      end

      it do
        puts 'it in context B'
      end

      context 'C' do
        before do
          puts 'before in context C'
        end

        it do
          puts 'it in context C'
        end
      end
    end
  end
end

実行結果

❯ bundle exec rspec
before in configure
before in describe
before in context A
before in context B
it in context B
.before in configure
before in describe
before in context A
before in context B
before in context C
it in context C
.

Finished in 0.00475 seconds (files took 0.10604 seconds to load)
2 examples, 0 failures

ドキュメント通り、 RSpec.configure 内で設定された before が一番最初で、その後は 上の階層にある before から順番に実行されるようですね。

Discussion