0.0
The project is in a healthy, maintained state
rspec-rewind provides deterministic retry policies, exception filters, configurable backoff strategies, and flaky test observability for RSpec.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 3.12, < 4.0
 Project Readme

rspec-rewind

Deterministic retry orchestration for flaky RSpec examples.

Gem Version CI License: MIT

rspec-rewind retries RSpec examples with explicit retry counts, exception filters, backoff strategies, retry budgets, and flaky-test reporting.

Installation

gem "rspec-rewind"

Then run:

bundle install

Usage

Require rspec/rewind from your RSpec setup file. This installs the around hook automatically.

# spec/spec_helper.rb
require "rspec/rewind"

RSpec::Rewind.configure do |config|
  config.default_retries = 1
  config.retry_on = [Net::ReadTimeout, Errno::ECONNRESET]
  config.skip_retry_on = [NoMethodError]
  config.backoff = RSpec::Rewind::Backoff.exponential(base: 0.1, factor: 2.0, max: 1.0)
  config.retry_budget = 20
  config.flaky_report_path = "tmp/rspec-rewind/flaky.jsonl"
end

Retry counts are extra attempts. rewind: 2 can run the example up to three times total.

it "eventually becomes consistent", rewind: 2 do
  expect(fetch_remote_state).to eq("ready")
end

Per-Example Controls

it "retries transient API failures",
   rewind: 3,
   rewind_wait: 0.2,
   rewind_retry_on: [Net::ReadTimeout, /502/],
   rewind_skip_retry_on: [NoMethodError],
   rewind_if: ->(exception, _example) { exception.message.include?("gateway") } do
  expect(call_api).to eq(:ok)
end
Key Meaning
rewind Extra retry count. true uses the configured default; false disables retries.
rewind_wait Fixed delay before the next attempt.
rewind_backoff Numeric or callable backoff strategy.
rewind_retry_on Additional retry allow-list matchers.
rewind_skip_retry_on Additional retry deny-list matchers. Checked before allow-list matchers.
rewind_if Predicate that decides whether the failure should retry.

retry_on and skip_retry_on matchers can be exception classes, regexps, or callables.

Backoff

RSpec::Rewind::Backoff.fixed(0.2)
RSpec::Rewind::Backoff.linear(step: 0.1, max: 1.0)
RSpec::Rewind::Backoff.exponential(base: 0.1, factor: 2.0, max: 2.0, jitter: 0.2)

Observability

Use callbacks when you want to send retry events to logs or metrics.

RSpec::Rewind.configure do |config|
  config.retry_callback = ->(event) { warn "[retry] #{event.example_id} attempt=#{event.attempt}" }
  config.flaky_callback = ->(event) { warn "[flaky] #{event.example_id}" }
end

Set flaky_report_path to write flaky examples as JSONL:

RSpec::Rewind.configure do |config|
  config.flaky_report_path = "tmp/rspec-rewind/flaky.jsonl"
end

Environment

RSPEC_REWIND_RETRIES=2 bundle exec rspec
RSPEC_REWIND_DISABLE=1 bundle exec rspec

RSPEC_REWIND_RETRIES takes priority over configured defaults and metadata.

Compatibility

  • Ruby >= 3.1
  • RSpec Core >= 3.12, < 4.0

Development

bundle install
bundle exec rake spec
bundle exec rake rubocop
bundle exec rake rbs

License

Released under the MIT License.