🐘
RSpec の before の順番を調べてみた
はじめに
RSpec の before
の実行される順番、よくわからなくないですか?
調べてみると let
と let!
、 before
など、別のブロック間の実行順序などは出てくるんですが、 context
が複雑にネストしていて、かつそれぞれに before
ブロックが存在する場合、どういった順番で実行されるのか、検索して調べてもあまり出てこないですよね。順番に依存しない before
ブロックを書ければ良いですが、必ずしもそうじゃありません。
今回の記事では、before
が様々なブロックに散らばっている場合、各テスト前にどの順番で実行されるか調べてみました。
RSpec とは
Rubyのテスティングフレームワークです。
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)
について着目すると、
-
RSpec.configure
内で宣言されたbefore(:example)
- 親グループで宣言された
before(:example)
- 現在のグループで宣言された
before(:example)
が、順番に it
や example
の前に実行されるみたいですね。
実際に動かして確かめてみましょう。
実際に実行してみる
環境
❯ 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