こんにちは、tonnyです。
最近、私たちはRailsのテストにRspecを使用しております。
(テストレコードの作成にはFactoryGirlを使用しています。)
今回は私たちのグループ内における基本的な使用ルールについて記載したいと思います。
その1と題しておりますが、その2があるかは未定です。
使っている中で、ルールを更新した場合は、その2、その3としてブログを書いていきたいと思います。
RspecにしろFactoryGirlにしろ、それに沿った使い方をしていれば問題ないのではないか?
当初は私たちもそう考えておりました。
しかし、RSpecやFactoryGirlが優秀すぎるため、以下の悩みが生じました。
このような問題への一つの解として、基本的なルールを設けることとしました。
Rspecには他にもspecifyやexampleも存在しますが、基本は上記の3つの階層でテストを分類します。
また、どうしてもcontextとitの間に階層がほしい場合はspecifyの使用を許可しています。
(ただ、現状specifyを利用するといったテストはないので、そこまで必要ではないのかもしれません。)
describe 'Item#add' do context '同一の商品名がない場合' do it 'successが返る' do expect(Item.add('pokemon')).to eq('success') end end context '同一の商品名がある場合' do it 'falseが返る' do expect(Item.add('pokemon')).to eq('false') end end end
これはテスト実行速度を少しでもあげるための策です。
ApplicationRecord.transaction do # テストレコードの作成 end
FactoryGirlの方が特にパフォーマンスなどに影響を与えるため、試行錯誤しております。
デフォルトのモデルは初期値を与えるだけで、個別に値設定したい場合は、createメソッドの引数で指定する。
ただし、以下の条件の場合は作成できます。
これは、パーツの名前と継承したモデル名で、どんなモデルなのか判断しやすいためです。
例えば、itemsテーブルにカテゴリを定義するcategoryカラムがあったとします。
1〜4までのカテゴリがあり、それぞれにenumでカテゴリ名が定義されているとします。このような場合は、traitとそれを継承したモデルを作成します。
trait :game do category 1 end factory :item_game, traits: [:game], parent: :item
trait :past do started_at Time.now.yesterday.beginning_of_day ended_at Time.now.yesterday.end_of_day end factory :item_past, traits: [:past], parent: :item
関連データを作成してくれることは非常に便利ですが、テストが遅くなる原因となります。
また、別に関連データ自体必要ない人もいるため、こちらもtraitでパーツにして必要な人のみ使用します。
# Item belongs_to Companyとします trait create_company do company end factory :item_create_company, traits: [:create_company], parent: :item
現状まとめますと、以上になります。
今後もRSpec、FactoryGirlは使用していこうと思いますので、ルールを更新したら、その2、その3というかたちで記事を書いていきたいと思います。
また、このブログを読んだ方で、何かご意見などございましたらコメントをお待ちしております!