hamayuzinの日記

エンジニアとかデータサイエンティストとかやってます。あの時 あれやってたな的な備忘録にできれば。

【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の削除方法が異なり 場合によっては、早くなる