@jnchito さんの指摘で、本件について原因を追究して、再修正します。
背景
featureのrspecの中に、
複数シナリオの共通部分のテストをリファクタリングしたいです。
featureをspecファイル下記のように記述しました。
after内のテストがエラーが発生しました。
require 'rails_helper'
feature 'guest add item to the cart', type: :feature do
after do
# シナリオ'a'実行後、絶対通れると思ったが、エラーが発生します。
expect(current_path).to eq cart_path
end
describe 'non sign in user' do
context 'when add a new item to cart' do
scenario 'a' do
# 通れたケースです
...
end
scenario 'b' do
# まだ書いていません。
end
end
end
end
原因
まず、テストの書き方を置いといて、
上記のテストが失敗した原因を説明しますと。
実行順番は下記の(1)-(4)
require 'rails_helper'
feature 'guest add item to the cart', type: :feature do
after do
# シナリオ'a'実行後、絶対通れると思ったが、エラーが発生します。
# (2) (4 ×)
expect(current_path).to eq cart_path
end
describe 'non sign in user' do
context 'when add a new item to cart' do
scenario 'a' do
# 通れたケースです
# (1)
...
end
scenario 'b' do
# まだ書いていません。
# (3)
end
end
end
end
after
=after(:each)
、実行タイミングは各シナリオごとです。
そのために、シナリオaが実行成功しましたが、
シナリオbが定義されたが、実施内容は何も書いていないので、
空実行後after
の内容を実施されると、エラーになります。
テスト書き方の間違い
@jnchito さんが指摘の通りですが、after
ブロック内に、expect
のケースを書くのが
間違いです。
after
ブロックに書くべきなのは、テスト実施後の後処理です。(例:ログアウト、データクリアなど)
テストの修正方法
そして、今回の件で、
各シナリオの一部共通部分だけを抽出で記述することよりは、
シナリオの分割方法から考えて、わかりやすく修正することです。
@jnchito の指摘のように、
RSpec入門・その1にも書きましたが、テストはDRYさよりも読みやすさやシンプルさの方が大事です。