よくコケる不安定な feature spec への対処療法 rspec-retry gem

背景

業務で開発している Web サービスの feature spec が非常に不安定で、feature spec が CI 上でコケるたびに、ビルドジョブをよく手動で再実行していました。1 回の再実行でパスすることもあれば、まれに 10 回以上の再実行が必要なこともありました。

その Web サービスでは、CI のジョブ終了までに約 8 分(中央値)かかります。つまり、リトライの回数が増えるたび、大体 8 の倍数分リリースに要する時間が増加してしまいます。

このような状態だと、価値をユーザに早く届けられなくなってしまうし、個人的にもフラストレーションがたまっていたので、 2 ヶ月前に rspec-retry gem を導入しました。

rspec-retry gem

rspec-retry gem は、RSpec の example に :retry オプションを追加し、spec が成功するまでオプションで指定した回数だけリトライしてくれる gem です。

今回は、fail しやすい feature spec 全体に対して、retry オプションを付与するようにしました。

RSpec.configure do |config|
  # run retry only on features
  config.around :each, type: :feature do |ex|
    ex.run_with_retry retry: 3
  end

  config.verbose_retry = true
  config.display_try_failure_messages = true
end

導入した結果

以下の画像は、その Web サービスの CircleCI の Insights から見られるグラフで、縦軸が完了までにかかった時間、横軸がビルドの実行日時です。縦棒は、すべてのジョブではなく、ある時点でサンプルしたジョブで、緑が成功したジョブ、赤が失敗したジョブを表しています。

結果はグラフの通りで、rspec-retry 導入以降はジョブ実行中のリトライが効いたことで、手動でリトライを行うことがほとんどなくなりました。素晴らしい!

f:id:nyamadori:20171119192821p:plain

とはいえ、あくまでこの方法は対処療法で、本来ならリトライが必要にならない spec に修正するのが根本対策です。同じように困っている方がいたらお試しあれ。

リンク