All Ruby on Rails templates

Rails Testing with RSpec

RSpec setup, factories, system specs, request specs, and fast suites.

DevZone Tools1,090 copiesUpdated Mar 23, 2026Ruby on Rails
# CLAUDE.md — Rails Testing with RSpec

## Setup

- **rspec-rails** + **factory_bot_rails** + **faker** + **shoulda-matchers** + **capybara** (for system specs).
- Run with `bin/rspec`. Parallel via `parallel_tests` if your suite is slow enough to matter.
- One spec per file under test: `spec/models/user_spec.rb` mirrors `app/models/user.rb`.

## Factories over fixtures

- Factories live in `spec/factories/`. One file per model.
- Use `Faker` for realistic strings — but seeds the same way every run for stability (`Faker::Config.random = Random.new(42)` in `rails_helper`).
- Traits for variations: `factory :user do; trait(:admin) { role :admin } end`.

## Spec types

- **Model specs** — validations, scopes, methods. Fast.
- **Request specs** — full HTTP round-trip. Replaces controller specs.
- **System specs** — Capybara + headless Chrome for end-to-end flows.
- Skip controller specs and view specs in new projects. Request and system specs cover their ground.

## Database

- `transactional_fixtures = true` in most cases — each example runs in a transaction that rolls back.
- For multi-thread (system specs with JS), use **DatabaseCleaner** with `:truncation` strategy.
- Don't share state across examples via class-level mutable variables.

## Mocks & stubs

- `instance_double(SomeClass, method: value)` — verifies the doubled class actually has the method.
- `allow(...).to receive(...)` for stubs (no expectation). `expect(...).to have_received(...)` for verification *after* the action.
- Don't mock the framework. If you mock `User.find`, you're testing at the wrong level.

## System specs

- Use Capybara's `expect(page).to have_content(...)` and `have_selector(...)` — they retry, accommodating async work.
- Avoid `sleep`. If retry-based matchers don't work, the page isn't ready and the test will be flaky.
- Run headless in CI; with a visible browser only when debugging locally.

## Speed

- Tag slow specs (`:slow`) and exclude from default runs.
- `before(:all)` is risky — state leaks across examples. Prefer `before(:each)`.
- Use `--profile 10` to find your slowest examples.

## Conventions

- One assertion per example where possible. Two when they're tightly related.
- `describe` for classes/methods, `context` for situational variants ("when admin", "when guest").
- Error messages are read from the matcher — don't add your own unless it adds info.

## Don't

- Don't load Rails for pure-Ruby unit tests. `spec_helper.rb` for those, `rails_helper.rb` for Rails-dependent.
- Don't hit external APIs in tests. Stub with **WebMock** + **VCR** (or just WebMock for predictable scenarios).
- Don't test private methods directly. They're tested through the public surface.
- Don't disable specs. Either fix or delete.

Other Ruby on Rails templates