【Rails/rspec】Railsのrsecテスト時間を半分以下にした話
Rails5のアプリケーションで、rspecテストを動かしている。 よくある話で、circle ci上で30分も時間がかかっていた。
時間がもったいないので、早くできないか調べた話。 やったことは、そもそも基本なことが多く 今回は、並列実行はしていない。 それでも、12分台になった。
featureテスト周り
capybara + Poltergeist環境
無駄な読み込みや遷移をなくす
いらないjs: trueの削除
jsの処理がある場合に、js: true
にする。
jsの処理がないのに、true
にしている場合があるので確認する。
js: true
にすると、jsの読み込みが完了するのを、待ってしまう。
scenario 'fugafuga', js: true do hogehoge end
いらない遷移をなくす
featureテストなので、画面遷移をどうしてもしたくなる。 テストに関係ない遷移はなくす。 意外と時間短縮になる。
下記の例の場合、 - 本当に TOPに最初遷移する必要があるのか - 最初にCSVアップロードページに遷移してはいけないのか 検討できる。
scenario 'CSVがアップロードできる', js: true do visit 'TOP' visit 'CSVアップロードページ' hogehoge # CSVアップロード操作 end
ログイン処理を毎回しない
deviseを使った認証や、独自の認証があるが テストを走らせる度に、ログイン画面を通したりしてないか。 (今回はしてた)
loginのテストは別途書くとして 他のテストでは、ログインしたこととすることはできないか。
allow_any_instance_of(ApplicationController).to receive(:authenticate).and_return(account)
その他テスト周り
よけいなcreateがないか
そのcreateは本当に必要か? createするとDBに書き込みが走る。 書き込みしないだけで、スピードアップが図れる
modelのテストに よくあるイメージ
let(account){ create(:account) }
ではなく
let(account){ build(:account) }
database_cleanerの設定
truncation
ではなく、transaction
を使う
テスト終了後のDBの削除方法が異なり 場合によっては、早くなる