しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

rspec-retryでfeature specを安定させる

rspec-retryという、失敗したテストを再実行するGemを使ってみました。

GitHub - NoRedInk/rspec-retry: retry randomly failing rspec example

まずはRailsのプロジェクトを作ってfeature specを書きます。

require 'rails_helper'

feature 'test' do
  scenario 'ページが表示される' do
    visit users_path

    expect(current_path).to eq users_path
  end
end

ここに一回目だけ失敗する処理を追加します。

require 'rails_helper'

i = 0
feature 'test' do
  scenario 'ページが表示される' do
    i += 1
    raise if i == 1
    visit users_path

    expect(current_path).to eq users_path
  end
end

これを実行するとエラーになります。

f:id:llcc:20170510000358p:plain

次はrspec-retryでエラーが出たら何回かリトライするようにします。
まずはGemfileにrspec-retryを追加します。

group :development, :test do
  gem 'rspec-retry'
end

次はspec_helper.rbにrspec-retry関連の設定を追加します。

require 'rspec/retry'

RSpec.configure do |config|
  config.verbose_retry = true
  config.display_try_failure_messages = true
end

最後にscenarioにretry回数を追加します。

require 'rails_helper'

i = 0
feature 'test' do
  scenario 'ページが表示される', retry: 3 do
    i += 1
    raise if i == 1
    visit users_path

    expect(current_path).to eq users_path
  end
end

実行すると、1回目で失敗したけど2回目で成功したことが分かります。

f:id:llcc:20170510000835p:plain

retryはscenarioではなくfeatureに付ける事もできます。

require 'rails_helper'

i = 0
feature 'test', retry: 3 do
  scenario 'ページが表示される' do
    i += 1
    raise if i == 1
    visit users_path

    expect(current_path).to eq users_path
  end
end

feature spec以外で使う事もできます。

require 'rails_helper'

i = 0
RSpec.describe User, type: :model, retry: 3 do
  it do
    i += 1
    raise if i == 1
    expect(1).to eq 1
  end
end

f:id:llcc:20170510001152p:plain

全feature specを対象にしたい場合は、spec_helper.rbに以下に設定を追加します。

require 'rspec/retry'

RSpec.configure do |config|
  config.verbose_retry = true
  config.display_try_failure_messages = true
  config.around :each, type: :feature do |ex|
    ex.run_with_retry retry: 3
  end
end