プロジェクトの RSpec をみていて、 include_context 〜
という文章があり共通処理をしているっぽいけど、どういうものなのか知らなかったので調べたメモ
include_context
ref. shared context - Example groups - RSpec Core - RSpec - Relish
shared_context 〜
で定義された共通処理を include する
e.g.
# shared/login.rb 共通処理 RSpec.shared_context 'login as user' do let(:login_user) { create :user } before { sign_in_as login_user } end # page_spec.rb 共通処理を使うテスト RSpec.describe 'Page' do # 共通処理 login as user を読み込み include_context 'login as user' describe '...' do # ... end end
↓ page_spec.rb
のテスト実行時には次のように解釈される
RSpec.describe 'Page' do # include_context している内容がここに入り実行されるということらしい。 let(:login_user) { create :user } before { sign_in_as login_user } describe '...' do # ... end end
shared_context
で定義する共通処理の名前は文字列でスペースを含んでもOKっぽい。
shared_context
を shared_examples
、 include_context
を include_examples
としてもいいらしい。(エイリアスになってるらしいけど、ドキュメントが別ページになってるのでチョットよく理解できてない。
cf. shared examples - Example groups - RSpec Core - RSpec - Relish
include_context の注意点
スコープ?を作らずに処理がそのまま include されるので、let
など同じ名前の定義があると上書きされてしまう。
RSpec.shared-examples "sample 1" do let(:name) { '星宮いちご' } it '名前が"星宮いちご"であること' do expect(name).to eq('星宮いちご') end end RSpec.shared-examples "sample 2" do let(:name) { 'ジョニー別府' } it '名前が"ジョニー別府"であること' do expect(name).to eq('ジョニー別府') end end RSpec.describe 'Sample' do include_context 'sample 1' include_context 'sample 2' end
↓ 次のように解釈されるので、name
が上書きされてしまい、sample 1 の 名前が"星宮いちご"であること
のテストが落ちる
RSpec.describe 'Sample' do let(:name) { '星宮いちご' } it '名前が"星宮いちご"であること' do expect(name).to eq('星宮いちご') end let(:name) { 'ジョニー別府' } it '名前が"ジョニー別府"であること' do expect(name).to eq('ジョニー別府') end end
it_behaves_like
it_behaves_like
を使うとcontext
を作りネストして include されるので、定義の上書きを回避できる
RSpec.describe 'Sample' do it_behaves_like 'sample 1' it_behaves_like 'sample 2' end
↓
RSpec.describe 'Sample' do context 'it_behaves_like sample 1' do let(:name) { '星宮いちご' } it '名前が"星宮いちご"であること' do expect(name).to eq('星宮いちご') end end context 'it_behaves_like sample 2' do let(:name) { 'ジョニー別府' } it '名前が"ジョニー別府"であること' do expect(name).to eq('ジョニー別府') end end end
docker 上で Rails 動かしてるけど、テストコマンド走らせるのに超時間が掛かるから、細かい所は実際に試してません。
[参考]
- 【RSpec】include_context, include_examples, it_behaves_like の違い - Qiita
- shared context - Example groups - RSpec Core - RSpec - Relish
- RSpecのshared_examplesとかshared_examples_forとか - Qiita
- https://codeday.me/jp/qa/20190120/150567.html
- ruby - What's the difference between "include_examples" and "it_behaves_like"? - Stack Overflow
- Railsチュートリアルの第4版をRSpecでテスト-3 - Qiita