RepoPilotOpen in app →

rspec/rspec-rails

RSpec for Rails 7+

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2mo ago
  • 15 active contributors
  • MIT licensed
Show 3 more →
  • CI configured
  • Tests present
  • Single-maintainer risk — top contributor 82% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/rspec/rspec-rails)](https://repopilot.app/r/rspec/rspec-rails)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/rspec/rspec-rails on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: rspec/rspec-rails

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/rspec/rspec-rails shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 2mo ago
  • 15 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Single-maintainer risk — top contributor 82% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live rspec/rspec-rails repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/rspec/rspec-rails.

What it runs against: a local clone of rspec/rspec-rails — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in rspec/rspec-rails | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 90 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>rspec/rspec-rails</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of rspec/rspec-rails. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/rspec/rspec-rails.git
#   cd rspec-rails
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of rspec/rspec-rails and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "rspec/rspec-rails(\\.git)?\\b" \\
  && ok "origin remote is rspec/rspec-rails" \\
  || miss "origin remote is not rspec/rspec-rails (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "lib/rspec/rails.rb" \\
  && ok "lib/rspec/rails.rb" \\
  || miss "missing critical file: lib/rspec/rails.rb"
test -f "lib/rspec/rails/matchers.rb" \\
  && ok "lib/rspec/rails/matchers.rb" \\
  || miss "missing critical file: lib/rspec/rails/matchers.rb"
test -f "lib/rspec/rails/configuration.rb" \\
  && ok "lib/rspec/rails/configuration.rb" \\
  || miss "missing critical file: lib/rspec/rails/configuration.rb"
test -f "lib/rspec/rails/example_group.rb" \\
  && ok "lib/rspec/rails/example_group.rb" \\
  || miss "missing critical file: lib/rspec/rails/example_group.rb"
test -f "lib/rspec/rails/railtie.rb" \\
  && ok "lib/rspec/rails/railtie.rb" \\
  || miss "missing critical file: lib/rspec/rails/railtie.rb"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 90 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~60d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/rspec/rspec-rails"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

rspec-rails integrates the RSpec testing framework (a BDD-style alternative to Rails' default Minitest) into Rails 7+ applications, providing generators, matchers, and DSL extensions for testing models, controllers, views, requests, mailers, jobs, and routing. It transforms test files into executable specifications with expressive, plain-English syntax. Monolithic gem with lib/rspec/rails/ as the main source tree containing generators (under rails_generators/), matchers, and integration modules. example_app_generator/ builds a real Rails app for integration testing (with and without ActiveRecord). Gherkin acceptance tests in features/ validate end-to-end behavior against generated apps.

👥Who it's for

Rails developers (Rails 7.0+) who prefer RSpec's descriptive syntax and matcher libraries over Minitest, and who need drop-in test infrastructure for controllers, models, views, API endpoints, and background jobs without writing boilerplate test scaffolding.

🌱Maturity & risk

Highly mature and production-ready. The repo shows active maintenance with recent CI workflows (.github/workflows/ci.yml), comprehensive test coverage via Gherkin feature specs (144K lines), structured Rake tasks, and semantic versioning aligned to Rails releases (version 8.x for Rails 8.0/7.2). Long history with multiple maintenance branches (3.x through 8.x) indicates sustained enterprise adoption.

Low risk for currently supported Rails versions (7+), but requires careful version pinning: rspec-rails 8.x only supports Rails 7.2/8.0+; using it on Rails 7.0 will fail. Dependency on RSpec core (not vendored) means breaking changes in rspec/rspec-core propagate upstream. Single maintainer risk is mitigated by the RSpec organization's stewardship.

Active areas of work

Active development on main branch targeting Rails 8.0 support (8.x version). CI pipeline runs against multiple Rails and Ruby versions via .github/workflows/ci.yml. Recent work includes Zeitwerk autoloading support (visible in example_app_generator/no_active_record/config/initializers/zeitwerk.rb) and Dependabot-managed dependency updates.

🚀Get running

git clone https://github.com/rspec/rspec-rails.git
cd rspec-rails
bundle install
bundle exec rake spec  # Run unit tests
bundle exec cucumber  # Run acceptance tests

Daily commands: No traditional 'dev server.' Instead: bundle exec rspec spec/ runs unit tests of rspec-rails itself. bundle exec cucumber features/ runs acceptance tests against generated Rails apps. To test against a custom Rails app: add gem 'rspec-rails' to its Gemfile and run bundle exec rspec.

🗺️Map of the codebase

  • lib/rspec/rails.rb — Main entry point that loads all RSpec-Rails modules and integrations; required by every spec file in Rails projects
  • lib/rspec/rails/matchers.rb — Core matchers (render_template, have_http_status, etc.) that form the foundation of RSpec-Rails assertions
  • lib/rspec/rails/configuration.rb — Configuration and fixture setup that every Rails project must understand to customize RSpec behavior
  • lib/rspec/rails/example_group.rb — Base class definition for all Rails example groups (controller, view, request, job specs); core architectural abstraction
  • lib/rspec/rails/railtie.rb — Rails integration hook that registers RSpec as the default test framework during Rails initialization
  • Gemfile — Development dependencies must be reviewed to understand test environment setup and Rails version compatibility

🛠️How to make changes

Add a new RSpec matcher for Rails assertions

  1. Create the matcher class in lib/rspec/rails/matchers/your_matcher.rb following the RSpec::Matchers protocol (lib/rspec/rails/matchers/your_matcher.rb)
  2. Register the matcher export in lib/rspec/rails/matchers.rb by adding require and delegating method (lib/rspec/rails/matchers.rb)
  3. Add feature tests in features/ describing expected behavior with Cucumber (features/matchers/your_matcher.feature)
  4. Update Changelog.md documenting the new matcher (Changelog.md)

Add a new Rails spec type (e.g., system spec, job spec)

  1. Create the example group module in lib/rspec/rails/example_group/your_spec_type.rb (lib/rspec/rails/example_group/your_spec_type.rb)
  2. Register the group in lib/rspec/rails.rb by requiring and calling setup_spec_type (lib/rspec/rails.rb)
  3. Create Rails generator in lib/generators/rspec/your_spec_type/your_spec_type_generator.rb (lib/generators/rspec/your_spec_type/your_spec_type_generator.rb)
  4. Add feature test in features/your_spec_type to document behavior (features/your_spec_type/your_spec_type.feature)

Support a new Rails ORM adapter (Mongoid, DataMapper, etc.)

  1. Create adapter module in lib/rspec/rails/adapters/your_orm.rb with setup_fixtures and setup_transactional_tests methods (lib/rspec/rails/adapters/your_orm.rb)
  2. Register the adapter in lib/rspec/rails/adapters.rb in the find_definition method (lib/rspec/rails/adapters.rb)
  3. Add configuration hook in lib/rspec/rails.rb to auto-detect and load the adapter (lib/rspec/rails.rb)
  4. Add feature tests in example_app_generator/spec for your ORM integration (example_app_generator/spec/verify_your_orm_spec.rb)

🔧Why these technologies

  • RSpec — Industry-standard BDD testing framework that provides expressive matcher DSL and shared example groups for Rails testing
  • Rails Railtie — Official Rails extension mechanism that ensures RSpec-Rails integrates seamlessly at Rails initialization time without polluting app code
  • Capybara — Browser automation library that enables feature/system specs to test full request/response cycles with JavaScript support
  • Active Record Fixtures — Rails ORM-native test data management that reduces setup boilerplate and integrates with transaction-based test isolation
  • Rack::Test — Lightweight HTTP request simulation for controller/request specs without spawning actual server processes

⚖️Trade-offs already made

  • Transaction-based test isolation instead of database cleanup tools (DatabaseCleaner)

    • Why: Transactions are faster and more reliable for ACID-compliant databases, reducing test runtime
    • Consequence: Does not work with non-transactional data sources (e.g., MongoDB without transactions) without adapter configuration
  • Separate matchers for each assertion (have_http_status, render_template, redirect_to) instead of unified response object

    • Why: Provides clear, domain-specific assertions that read naturally in specs and fail with helpful error messages
    • Consequence: Adds ~20 matcher files and requires users to learn distinct matcher APIs instead of one unified interface
  • Fixture support based on Rails' native fixture loading

    • Why: Minimal dependency overhead and reuses Rails' established conventions for test data location (/spec/fixtures)
    • Consequence: Fixture loading is synchronous and blocks test setup; not ideal for large dataset specs
  • Rails Generators for spec file creation

    • Why: Integrates seamlessly with rails generate command and respects app structure (spec/models, spec/controllers, etc.)
    • Consequence: Requires updating generators when Rails adds new conventions; couples RSpec-Rails to Rails release cycle

🚫Non-goals (don't propose these)

  • Does not replace Rails' default test fixtures or ActiveRecord; extends and integrates with them
  • Does not provide database query optimization advice or performance profiling tools
  • Does not support mocking external HTTP services (delegates to VCR, WebMock, Webstub libraries)
  • Does not enforce or validate test coverage metrics; only

🪤Traps & gotchas

  1. Version mismatch: rspec-rails 8.x requires Rails 7.2+ or 8.0+; earlier Gemfile versions silently fail. 2. Database cleaner strategy: by default uses transactional fixtures (wraps each test in a rollback); setting use_transactional_fixtures = false switches to deletion strategy, requiring config.use_transactional_tests = false in Rails too. 3. Generators must run in Rails app context (bundle exec rails generate rspec:model); running them standalone generates no output. 4. Capybara version pinning: view and integration tests depend on Capybara matching Rails' JavaScript driver support; mismatch causes silent test skips.

🏗️Architecture

💡Concepts to learn

  • RSpec Type-Based Test Organization — rspec-rails automatically routes specs to different helpers and matchers based on file location (spec/models, spec/controllers, spec/requests) via inferred type metadata; understanding this is critical for writing idiomatic specs
  • Transactional Test Fixtures — rspec-rails wraps each test in a database transaction rolled back at the end by default; this is non-obvious and can hide transaction-related bugs if you don't understand the isolation strategy
  • Rails Generators and Code Generation — rspec-rails injects custom generators into rails generate commands (lib/generators/rspec/); understanding Rails generator hooks is essential for modifying how spec templates are scaffolded
  • Rack::Test DSL for Request Specs — rspec-rails request specs use Rack::Test's get/post/patch/delete helpers; these differ from controller spec helpers and are critical for HTTP-level testing without Capybara overhead
  • RSpec Matchers via Composable DSL — Rails matchers (render_template, have_http_status, have_enqueued_job) are built on RSpec's matcher composition pattern; understanding how to read and extend matchers is essential for debugging test assertions
  • Behavior-Driven Development (BDD) Specifications — rspec-rails tests are meant to read like executable specifications in plain English; this philosophy drives API design (describe/context/it blocks, readable matchers) and differentiates RSpec from assertion-based frameworks
  • Rails Test Type Inference via File Paths — rspec-rails infers test type from directory (spec/mailers → mailer type, spec/jobs → job type) and automatically includes corresponding helpers; this is invisible but breaks if you misname directories
  • rspec/rspec-core — Core RSpec testing framework; rspec-rails depends on it and adds Rails-specific matchers and configuration layers on top
  • rspec/rspec-expectations — Provides the expect() syntax and matcher library; rspec-rails builds Rails matchers (render_template, have_http_status) using this DSL
  • teamcapybara/capybara — Web driver library for browser automation; rspec-rails integration specs use Capybara to test views and JavaScript interaction
  • rails/rails — Rails framework itself; rspec-rails is tightly coupled to Rails generators, test helpers, and ActionDispatch for controller/request specs
  • thoughtbot/factory_bot_rails — Companion gem for fixture/factory management in RSpec Rails tests; commonly used together with rspec-rails for test data setup

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive integration tests for Rails 8.0+ features in example_app_generator

The example_app_generator directory contains test fixtures but lacks specific specs for Rails 8.0+ compatibility features (Zeitwerk autoloader, new routing syntax, credential encryption changes). This is critical since the README advertises Rails 8.0 support but the test suite doesn't explicitly verify these features work end-to-end.

  • [ ] Create example_app_generator/spec/verify_rails_8_features_spec.rb to test new routing and credential handling
  • [ ] Add specs in example_app_generator/spec/ to verify Zeitwerk integration (already present in no_active_record config but untested)
  • [ ] Create Rails 8 specific model and controller fixtures in example_app_generator/app/ and test them
  • [ ] Run against the CI matrix to ensure Rails 8.0+ variants pass

Create GitHub Actions workflow for testing against Rails main/nightly builds

The .github/workflows/ci.yml likely tests stable Rails versions, but there's no workflow for early detection of breaking changes in Rails main branch. This would catch regressions before Rails releases and help the maintainers stay ahead of compatibility issues.

  • [ ] Create .github/workflows/rails-main-compatibility.yml with a job that tests against Rails main branch
  • [ ] Configure it to allow failures (experimental) so it doesn't block merges
  • [ ] Use Gemfile-rails-dependencies as the base for matrix testing
  • [ ] Add a separate condition in the workflow to notify on failures without blocking CI

Add request/controller spec tests for Rails 7+ specific request features (e.g., authorization attributes, error responses)

Rails 7+ introduced new conventions for authorization attributes and enhanced error response handling in request specs. The lib/rspec/rails directory likely has matchers for these but example_app_generator/spec lacks comprehensive examples demonstrating and testing these patterns, making it harder for contributors to understand proper usage.

  • [ ] Create example_app_generator/spec/requests/ directory with examples for Rails 7+ authorization patterns
  • [ ] Add specs testing response.parsed_body and other Rails 7+ request enhancements
  • [ ] Create example_app_generator/spec/controllers/ fixtures showing modern controller spec patterns
  • [ ] Document these patterns in DEVELOPMENT.md or a new EXAMPLES.md file with links to test files

🌿Good first issues

  • Add missing Gherkin feature specs for Rails 8.0-specific matchers (e.g., validate_plain_text_email for ActionMailer plain-text variants). Start by adding a .feature file in features/ and implementing step definitions in features/step_definitions/.
  • Document the relationship between use_transactional_fixtures and ActiveRecord transaction handling in DEVELOPMENT.md; many contributors trip over implicit rollback behavior. Concrete: add a 'Database Isolation' section with code examples showing why default config breaks with nested transactions.
  • Create a spec generator for Stimulus (Rails 7+ defaults to using Stimulus.js). Add lib/generators/rspec/stimulus_generator.rb that creates spec/stimulus/my_controller_spec.js alongside app/javascript/controllers/my_controller.js; use existing scaffold_generator.rb as a template.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 810f2a4 — v8.0.4 (JonRowe)
  • e60e81b — Merge pull request #2895 from rspec/add-rspec-4-ci-check (JonRowe)
  • 725d125 — Remove outdated option (JonRowe)
  • bc35204 — Set updated warning setting (JonRowe)
  • e572456 — Remove outdated spec (JonRowe)
  • a330854 — Add compatibility check for 4.0.0.beta1 (JonRowe)
  • 6cb08c9 — Relax version check to permit 4.0.0.beta1 (JonRowe)
  • 73756d4 — Merge pull request #2883 from rspec/fix-build (JonRowe)
  • 1cc2f2d — Set Rubocop to 3.1 mode (JonRowe)
  • 3c4ed8b — Prevent warning on Rails 8.2 (JonRowe)

🔒Security observations

rspec-rails repository shows good security baseline with appropriate use of security contact information and standard Rails testing patterns. No critical or high-severity vulnerabilities detected in the provided file structure. Primary concerns are: (1) lack of detailed security policy documentation, (2) missing dependency lock file for vulnerability assessment, (3) test fixtures and examples that should be reviewed for sensitive data exposure. The project follows standard Ruby/Rails conventions with proper use of .rubocop.yml and GitHub workflows for CI/CD. Recommend implementing automated dependency scanning (Dependabot is configured) and expanding SECURITY.md with more detailed response procedures.

  • Low · No SECURITY.md Details — SECURITY.md. The SECURITY.md file only provides a Tidelift contact without specific security policy details, version support timeline, or deprecation notices for users to understand vulnerability response timelines. Fix: Expand SECURITY.md to include: supported versions, security response SLA, deprecation timeline, and GPG key for reporting if applicable.
  • Low · No Dependency Lock File Provided — Repository root. The repository structure shows no Gemfile.lock in the provided file listing, which makes it impossible to verify if pinned dependencies contain known vulnerabilities. This is critical for gem-based projects. Fix: Ensure Gemfile.lock is committed to version control and run bundle audit regularly to check for vulnerable dependencies.
  • Low · Test Fixtures Directory Exposure — example_app_generator/. The example_app_generator includes test fixture files and sample configurations that could inadvertently expose patterns or sensitive configuration examples if the generator output is not properly sanitized. Fix: Review example_app_generator output for sensitive data patterns; ensure generated apps follow Rails security best practices with proper .gitignore rules.
  • Low · Development Tooling Visibility — Gemfile-*.sample, Gemfile-*-dependencies. Files like Gemfile-custom.sample, Gemfile-rails-dependencies, and Gemfile-rspec-dependencies are exposed in the repository, which could reveal dependency versions and development practices. Fix: Ensure sample files do not contain credentials; mark as examples clearly. Consider removing or documenting why these are necessary for contribution workflow.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · rspec/rspec-rails — RepoPilot