はじめに
こんにちは、tonnyです。
最近、私たちはRailsのテストにRspecを使用しております。
(テストレコードの作成にはFactoryGirlを使用しています。)
今回は私たちのグループ内における基本的な使用ルールについて記載したいと思います。
その1と題しておりますが、その2があるかは未定です。
使っている中で、ルールを更新した場合は、その2、その3としてブログを書いていきたいと思います。
そもそもなぜ基本ルールなどを作成しようとしたのか?
RspecにしろFactoryGirlにしろ、それに沿った使い方をしていれば問題ないのではないか?
当初は私たちもそう考えておりました。
しかし、RSpecやFactoryGirlが優秀すぎるため、以下の悩みが生じました。
- 学習コストが高い
便利な用法が数多く存在するが、それ故に統一感がなくなる可能性がある。 - 思わぬところでエラーが発生する可能性がある
特にFactoryGirlですが、Aさんが手の込んだテストモデルを作成し、Bさんがそれをまた改修した場合、Aさんが担当したテストに影響が出る可能性があります。 - テスト実行に時間がかかるようになる
せっかくだからと、コールバックメソッドを呼び続けると、全体で見たときのテスト実行に時間をとられることになってしまいます。
このような問題への一つの解として、基本的なルールを設けることとしました。
Rspec編
describe、context、itの階層で使用する
Rspecには他にもspecifyやexampleも存在しますが、基本は上記の3つの階層でテストを分類します。
- describe・・・テストしたい対象(ex. Item#add、items/index)
- context・・・テストの条件(ex. ログインに成功したとき or ログインに失敗したとき)
- it・・・リクエストパラメータの違いなどで生じる結果(ex. リクエストパラメータが◯○のときは△△)
また、どうしてもcontextとitの間に階層がほしい場合はspecifyの使用を許可しています。
(ただ、現状specifyを利用するといったテストはないので、そこまで必要ではないのかもしれません。)
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
10個以上のテストレコードを作成したい場合は、トランザクションを張る
これはテスト実行速度を少しでもあげるための策です。
1 2 3 4 | ApplicationRecord.transaction do # テストレコードの作成 end |
FactoryGirl編
FactoryGirlの方が特にパフォーマンスなどに影響を与えるため、試行錯誤しております。
デフォルトのモデルはきれいな状態で
デフォルトのモデルは初期値を与えるだけで、個別に値設定したい場合は、createメソッドの引数で指定する。
traitにてパーツを量産しない
ただし、以下の条件の場合は作成できます。
これは、パーツの名前と継承したモデル名で、どんなモデルなのか判断しやすいためです。
enumで定義されているカラム
例えば、itemsテーブルにカテゴリを定義するcategoryカラムがあったとします。
1〜4までのカテゴリがあり、それぞれにenumでカテゴリ名が定義されているとします。このような場合は、traitとそれを継承したモデルを作成します。
1 2 3 4 | trait :game do category 1 end factory :item_game, traits: [:game], parent: :item |
過去、未来、現在で固定する
1 2 3 4 5 | 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でパーツにして必要な人のみ使用します。
1 2 3 4 5 | # Item belongs_to Companyとします trait create_company do company end factory :item_create_company, traits: [:create_company], parent: :item |
さいごに
現状まとめますと、以上になります。
今後もRSpec、FactoryGirlは使用していこうと思いますので、ルールを更新したら、その2、その3というかたちで記事を書いていきたいと思います。
また、このブログを読んだ方で、何かご意見などございましたらコメントをお待ちしております!