Testing Rails applications: Minitest, RSpec, FactoryBot and Capybara

Rails has shipped with a testing framework since its first release, and the community has built an unusually rich set of tools around it. The choices that matter come down to four questions: which framework, how to build test data, how to drive a browser, and how to keep the suite fast.
Release figures are from RubyGems.org, October 2026.
Minitest or RSpec
New Rails applications use Minitest, through Rails' own ActiveSupport::TestCase and its subclasses for models, controllers, mailers, jobs and system tests. The Testing Rails Applications guide documents it in full. Tests are plain Ruby classes and methods with assertions, and the whole setup comes with the framework.
RSpec, integrated through rspec-rails (8.0.4, March 2026), offers a descriptive DSL with describe, context and it, a large matcher library, shared examples and rich metadata for filtering. It is the more common choice in Rails job listings and open-source applications.
RSpec.describe Invoice do
describe "#overdue?" do
it "is true once the due date has passed" do
invoice = build(:invoice, due_on: 2.days.ago, paid_at: nil)
expect(invoice).to be_overdue
end
end
end
Both are good. Minitest is smaller and faster to boot, and stays close to the framework; RSpec is more expressive and has the larger ecosystem of extensions. The worst choice is to mix both in one application.
Fixtures or FactoryBot
Rails fixtures are YAML files loaded once into the test database inside a transaction. They are fast and make relationships between records explicit, but grow hard to maintain when many tests need slightly different data.
FactoryBot (6.6.0, May 2026), with factory_bot_rails for the Rails integration, builds records on demand from factory definitions, with traits for variations. It was called factory_girl until 2017; the old factory_girl gem's last release, 4.9.0, dates from October 2017, and migrating is mostly a matter of renaming. Machinist, an older alternative with a "blueprint" syntax, is no longer maintained.
Factories are convenient but easy to overuse: a factory that silently creates five associated records for every test slows the suite down. Prefer build or build_stubbed when you do not need the database.
System tests and Capybara
For tests that exercise the whole stack through a browser, Rails 5.1 introduced system tests (ActionDispatch::SystemTestCase), built on Capybara. RSpec users write the same tests as system specs. Capybara's API reads like user actions:
visit new_session_path fill_in "Email", with: user.email fill_in "Password", with: "secret-password" click_on "Sign in" assert_text "Welcome back"
Capybara can drive Rack::Test (fast, no JavaScript), Selenium with a real browser, or Chrome through the DevTools protocol using Cuprite. Capybara's latest release, 3.40.0, dates from January 2024; it remains the standard and works with current Rails, but its release pace has slowed, which is worth watching.
Capybara replaced Webrat, the browser simulator of the Rails 2 era, whose API it deliberately resembled. Cucumber, for acceptance tests written in plain-language Gherkin, is still available through cucumber-rails (4.1.0, July 2026), though many teams now write system tests directly.
Useful companions
- shoulda-matchers (8.0.1, June 2026) gives one-line tests for validations and associations, for RSpec and Minitest.
- WebMock or VCR stop tests from making real HTTP requests, and record and replay responses.
- Rails' built-in time helpers (
travel_to,freeze_time) replace older gems for controlling time. - SimpleCov reports coverage; treat the number as a guide to untested areas, not a target.
Keeping the suite fast
A slow suite is a suite people stop running. In the Rails 2 and 3 days, the usual fix for slow boots was Spork, a server that preloaded Rails. Today:
- Parallel testing is built into Rails since 6.0 (
parallelize(workers: :number_of_processors)), and tools exist for RSpec too. - Bootsnap, included in new applications, caches expensive boot work.
- Spring keeps an application preloaded between commands; it is optional and no longer added to new applications by default.
- Fewer database writes: use
build_stubbed, avoid unnecessary associations in factories, and keep system tests for critical paths only.
Summary
| Need | Default | Popular alternative |
|---|---|---|
| Framework | Minitest | RSpec |
| Test data | Fixtures | FactoryBot |
| Browser tests | System tests with Capybara and Selenium | Cuprite driver |
| Speed | Parallel testing, Bootsnap | Spring |
Plugin historiesSpork
What Spork did for RSpec and Cucumber in the Rails 2 and 3 era, why it stopped at 1.0.0rc4, and how Spring, Bootsnap and parallel testing solve the same problem today.
Plugin historiesWebrat
What Webrat was, how it simulated a browser for Rails integration tests, why it stopped at version 0.7.3 in 2011, and how to migrate Webrat steps to Capybara and Rails system tests.
GuidesEvaluating a Rails gem
A practical checklist for judging a Ruby gem: maintenance signals, compatibility with Rails 7 and 8, dependencies, licence, and security advisories with bundler-audit.