Ruby on Railsのスローテスト対策で効果があったものなかったもの

こんにちは。みんなのウェディングのエンジニアの@1syoです。 みんなのウェディング Advent Calendar 2017 - Qiita 18日目の記事です。

Ruby on Rails のスローテスト対策としてやってみて、効果がなかったものとあったものをご紹介しようと思います。

効果がなかった

springを利用する

.circleci/config.yml

- run:
  command: bin/spring server
  background: true
- run: bin/spring rspec $(circleci tests glob "spec/** ...
- run: bin/spring rspec $(circleci tests glob "spec/** ...

このように spring server を起動してから spring 経由で RSpec を実行していましたが、実行時間に変化がなかったのでやめました。

feature specの時のウェブサーバーをpumaにする

Capybara.server = :puma, { Silent: true }

WEBrick より性能いいから早くなるのではと思いましが、実行時間に変化はありませんでした。

url_whitlistを利用してテスト時に外部のjavascriptを読み込まないようにする

url_whitlist: %w(
 127.0.0.1
)

外部のjavascriptを読み込まない分、速くなると思いましたが実行時間に変化はありませんでした。

test環境でログを出力しない

config.logger = Logger.new(nil).tap { |log| def log.write(msg); end }

ファイルの書き込みが減る分早く..(以下省略)

効果があった

テスト実行前に asset precompile する

もともとmasterブランチのtmp/cache/assets/ を独自スクリプトでAWSのS3にアップロードして、各ブランチのテストで再利用していました。一定のキャッシュ効果はあったもの、masterブランチとの差分が多いブランチのビルドには効果が薄い状況でした。
Circle CI 2.0 に移行したことをきっかけに Circle CI のキャッシュを利用するように変更し、さらにassets 配下に更新があった場合のみasset precompile するようにしました。feature spec が早くなった結果、テスト全体で30〜40%ほど実行時間が減りました。

Circle CI 2.0のキャッシュの活用方法はクラウドワークス様のブログを参考にさせてもらいました。ありがとうございます。
CircleCI 2.0に移行して新機能を活用したらCIの実行時間が半分になった話 - クラウドワークス エンジニアブログ

無用なevaluate.javascriptを消す

feature specで以下のようにクリックイベントをトリガーに execute_script している箇所がありました。Capybaraを利用している場合は意味がないので削除したところ60秒かかっていたテストが20秒ほどになりました。

page.execute_script("$('.js_search-condition-accordion').eq(0).trigger('click')")

コンテナを増やすとか多く分割するといった対策なしに全体をサクッと早くするのは難しく、プロファイルをとって個別のテストケースに対策を取らないと早くするのは難しいなと思いました。
こんなやり方は効果はあった!もしくはなかった!という経験のある方は是非教えてください。 みんなのウェディング Advent Calendar 2017 19日目はamyroi さんの記事です。


みんなのウェディングでは、一緒に働く仲間を募集しています。
スローテストを解消してサクサクプロダクトを作りたいエンジニアの方はWantedlyからご連絡ください。または @1syo にご連絡ください。