RSpec Order-Dependent Failures - Fix Random-Order Flake in CI
A spec passes in one order and fails in another because state leaks between examples. RSpec’s random ordering exposes it: data left in the DB, a mutated global, or a class variable carried across examples.
What this error means
CI fails with "Randomized with seed N" and an example that passes when run alone. Re-running with the same seed reproduces it; a different seed may hide it - the tell-tale of an order dependency.
Randomized with seed 51423
Failures:
1) OrdersController GET index returns only this user's orders
expected 2 orders, got 5
# passes alone; fails after another spec leaves orders behindCommon causes
Data not rolled back between examples
Records created in one example persist (no transactional fixtures, or a truncation strategy that did not run), so a later example sees unexpected rows.
Mutated global or class state
A class variable, constant, or global config changed in one example and not restored leaks into others depending on order.
How to fix it
Isolate database state per example
Use transactional fixtures or DatabaseCleaner so each example starts clean.
# rails_helper.rb
RSpec.configure do |config|
config.use_transactional_fixtures = true
endReproduce with the seed and isolate
- Re-run with the printed seed:
rspec --seed 51423to reproduce deterministically. - Bisect by running the failing example after suspected predecessors.
- Restore any global/class state you mutate in an
afterhook.
How to prevent it
- Keep
config.order = :randomso coupling surfaces early. - Use transactional fixtures or DatabaseCleaner consistently.
- Never share mutable global/class state across examples.