
こんにちは。Webエンジニアをしているotariidaeです。
テストは速ければ速いほど良いものです。善は急げということでさっそく速くしていきましょう。
なにを速くするか
今回速くしていくのは STORES を利用いただいている事業者向け管理画面のバックエンドのテストです。2025年1月から本格的に開発され始めたアプリケーションなので、まだまだ最適化の余地がたっぷり残っていそうですね。Ruby on Rails製で、テストフレームワークはRSpecを使っています。
どうやって速くするか
RSpecを速くするためにまずやることといえば、そう、プロファイリングですね。
TestProfのサンプリング機能とStackProfを使ってコールスタックを取得して、speedscopeで可視化してみましょう。

見るからに怪しいKernel.sleepとKernel#sleepがあります。
勝手にsleepするのやめてね。こっちは仕事でRSpec回してるんですけど😠
今回はこの2つを倒していきます。
Kernel.sleepを速くする
フレームグラフを見ると、Kernel.sleepはどうやらretryable gem由来のようです。

デフォルトでは1秒間sleepするようになっていたので、対策としてはこうですね。
# frozen_string_literal: true Retryable.configure do |config| # テストではデフォルトのsleep時間を短くして高速化を図る config.sleep = 0.01 end
この6行で、19秒ほどかかっていたテスト群が4秒未満になりました。5倍速い!
Kernel#sleepを速くする
Kernel#sleepの方も探ってみると、自前でリトライ処理を実装している箇所でした。

while attempts < @max_attempts && run.processing? sleep(@interval) run = @client.get_query_run(run.id) attempts += 1 end
デフォルトのリトライ間隔はクラス定数で定義されていたので、対策としてはこうですね。
stub_const("Zuora::DataQuery::Runner::DEFAULT_INTERVAL", 0.01.second)
テストの構造に合わせて4箇所に設定して、1分20秒ほどかかっていたテスト群が10秒ほどになりました。8倍速い!
まとめ
TestProfとStackProfを使うことで楽に速くできるテストを見つけ、たった10行で85秒もテストの実行時間を短縮できました。
テスト最適化としてはかなり初歩的でしたが、もしかしたらみなさんの周りにも意外と探索されていない最適化の余地が残っているかもしれません。
STORES ではシュッとテストを速くしたいエンジニアを募集しています。