Rails アプリケーションのテストが遅い要因はほぼ Feature Spec いうことで、こんな作業なんかもしてたりした。
無駄に DatabaseCleaner.strategy で :truncation を使っている箇所を :transaction を使うよう metadata をメンテしまわるだけの簡単なお仕事
— Koichi ITO (@koic) 2016年8月29日
まとめると、DatabaseCleaner.strategy
で :truncation
の実行は遅いので、必要がなければ :transaction
を使いたいという取り締まり作戦。
最初の確認点として、Feature Spec なんかを書いているアプリケーションの spec_helper.rb か rails_helper.rb に以下のような感じのロジックがあるかを見てみる。あれば example.metadata
で指定しているメタデータ名が取っ掛かりになる。ここでの容疑名は :javascript
としよう。
config.before(:each) do |example| if example.metadata[:javascript] DatabaseCleaner.strategy = :truncation, {except: MASTERS} else DatabaseCleaner.strategy = :transaction end end
スローテスト容疑の取っ掛かりの名前 (ここでは :javascript
) から、DatabaseCleaner.strategy
で :transaction
で済むところを :truncation
を実行されるようになっているところを調査する。
ここでの容疑の調査でいうとこんな感じで、grep の引数に与える。
grep -ro @javascript spec
あとは grep の一覧に出てきた対象のファイルを対象に、盲目的に フィーチャ
に @javascript
が付いているようなところを、必要な シナリオ
だけ @javascript
としていく。
-@javascript フィーチャ: 遅いフィーチャ シナリオ: JavaScirptを使わないシナリオ1 ... + @javascript シナリオ: JavaScriptを使うシナリオ ... シナリオ: JavaScirptを使わないシナリオ2 ...
もっと雑にいうと消すことのできる @javascript
はがっつりと消す。がっつり消せると埋蔵金ゲットだぜ感高い。
-@javascript
フィーチャ: 遅いフィーチャ
シナリオ: このフィーチャにあるシナリオどれもJavaScirptを使わない
...
大きめの効果が出たところでざっくりと、
Finished in 50.63 seconds (files took 7.32 seconds to load) 10 examples, 0 failures
から
Finished in 31.74 seconds (files took 6.31 seconds to load) 10 examples, 0 failures
とか
Finished in 51.63 seconds (files took 7.36 seconds to load) 16 examples, 0 failures
から
Finished in 33.91 seconds (files took 7.21 seconds to load) 16 examples, 0 failures
といった感じが期待できる (かもしれない) 。
ポイントとしては、上記のように10秒台単位でじわじわとではあるけど着実に減らせたりする点と、容疑の絞り込みが割と簡単という点。テスト並列化のあとくらいに考えてみると良いと思う。