RSpec before(:all)とbefore(:each)の違い
はまったのでメモ。
大きな違いは実行順番ではない
自分もそうなんですが:allと:eachの違いは実行順番だけだと思っていましたが実際は違います。 例えば下記のようなテストの場合
describe Account do context '#signin' do context 'メールアドレスとパスワードが一致していたら' do before(:all) @mail = 'hoge@mail.com' @password = '1234' Account.create(mail: @mail, password: @password) end after(:each) Account.delete_all end it 'サインイン出来る' do # テスト処理 end end end end
この処理はサインインできることをテストするために、必要なアカウントをbefire(:all)で用意し、 テスト実施後に用意したデータを消すつもりで書いています。
しかし消えません。
いろいろ調べた結果、:allと:eachは実行順番以外の違いがあることが分かりました。
:eachは変数の書き換えやトランザクション発行を全てそのスコープ内限定(今回だとit サインイン出来る)で利用出来るようにしています。
:eachで用意したデータは特定のitでのみ利用するいう意味合いを含むためこのような仕様になっているのかと思います。
ではなぜ用意したデータが消えないかという、after(:each)で発行したdelete_all(delete処理)が他のテストに影響しないよう、丁寧にロールバックされているためです。 :eachでのトランザクションは全てロールバックされるので、before(:each)でAccount.createすれば、特にdelete処理をする必要も無かったということで一件落着しました。