RSpec: expected X, got Y failure in CI
An expectation did not match: RSpec prints the expected and actual values. When this only happens in CI, the assertion is usually correct but the environment, ordering, time, or data differs from your machine.
What this error means
RSpec reports a failure with an "expected ... got ..." diff. The same spec passes locally. Common when the test depends on order, current time, locale/zone, or pre-existing data.
Failure/Error: expect(invoice.total).to eq(100)
expected: 100
got: 0
(compared using ==)Common causes
Order dependence
RSpec randomizes order; a spec that relied on state from another example fails when run in a different order in CI.
Time or timezone differences
The runner uses UTC or a different clock; date/time assertions that pass locally drift in CI.
Environment or seed data
A value read from ENV differs, or the test assumed seed data that does not exist on a fresh CI database.
How to fix it
Reproduce the CI conditions
- Re-run with the failing seed: bundle exec rspec --seed <printed-seed> to reproduce order dependence.
- Freeze time (Timecop/ActiveSupport::Testing::TimeHelpers) and set the zone explicitly.
- Make each example create its own data instead of relying on seeds or other specs.
bundle exec rspec --seed 12345 # reproduce the CI orderingPin environment-sensitive values
- Set TZ and locale in the CI env to match expectations.
- Read config from ENV with explicit test defaults.
- Use database cleaning between examples so state does not leak.
How to prevent it
- Keep examples independent and order-agnostic.
- Freeze time and pin the timezone in tests.
- Create per-example data rather than depending on seeds.