An RSpec cheatsheet in the form of a Rails app. Learn how to expertly test Rails apps from a model codebase
The repo contains examples of various spec types such as feature, mailer, and model. See the spec/ directory for all the example specs and types.
See the well-commented files in the spec/support directory for walkthroughs on how to configure popular testing gems, such as DatabaseCleaner, Capybara, and FactoryGirl.
PS. Interested in growing your skills and supporting this project? Learn with the TDD Masterclass, get Test Coverage First Aid for your app, or grow with one-to-one coaching for Rails developers.
- Support Configuration
- Run Specs in a Random Order
- Testing Production Errors
- Testing Rake Tasks with RSpec
- Pry-rescue debugging
- Time Travel Examples
- Database Cleaner Examples
- Factory Girl Examples
- Shoulda-Matchers Examples
- Custom Matchers
- RSpec-Expectations Docs
- RSpec-Mocks Specs & Docs
- RSpec-Rails
- Validator Specs
The tests rely on this configuration being uncommented in spec/rails_helper.rb
, you probably want it uncommented in your app too:
# Loads `.rb` files in `spec/support` and its subdirectories:
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
(The rspec-rails installer generates this line, but it will be commented out.)
In a dependable, repeatable automated test suite, data stores (such as database, job queues, and sent email on ActionMailer::Base.deliveries
) should return to a consistent state between each spec, regardless of the order specs are run in.
For a maintainable, predictable test suite, one spec should not set up data (e.g. creating users) needed by a later spec to pass. Each spec should look after its own test data and clear up after itself. (NB. If there is reference data that all tests need, such as populating a countries
table, then this can go in db/seeds.rb
and be run once before the entire suite).
The specs run in a random order each time the test suite is run. This helps prevent the introduction of run order and test data dependencies between tests, which are best avoided.
Random order test runs are configured using the config.order = :random
and Kernel.srand config.seed
options in spec/spec_helper.rb.
When errors are raised, the Rails test environment may not behave as in production. The test environment may mask the actual error response you want to test. To help with this, you can disable test environment exception handling temporarily, spec/support/error_responses.rb provides respond_without_detailed_exceptions
. See it in use in spec/api/v1/token_spec.rb to provide production-like error responses in the test environment.
pry-rescue can be used to debug failing specs, by opening pry's debugger whenever a test failure is encountered. For setup and usage see pry-rescue's README.
ActiveSupport::Testing::TimeHelpers
provides helpers for manipulating and freezing the current time reported within tests. These methods are often enough to replace the time-related testing methods that the timecop
gem is used for.
TimeHelpers
configuration how-to and examples:
Database Cleaner is a set of strategies for cleaning your database in Ruby, to ensure a consistent environment for each test run.
Database Cleaner configuration how-to:
Factory Girl is a library to help setup test data. factory_girl_rails integrates Factory Girl with Rails.
Factory Girl configuration how-to and examples:
- spec/support/factory_girl.rb
- spec/factories
- spec/factories/users.rb
- spec/models/subscription_spec.rb
Shoulda-matchers make light work of model specs.
shoulda-matchers configuration how-to and examples:
You can write your own custom RSpec matchers. Custom matchers can help you write more understandable specs.
Custom matchers configuration how-to and examples:
- spec/support/matchers.rb
- spec/matchers
- spec/matchers/be_pending_subscription_page.rb
- Chainable matcher: spec/matchers/be_confirm_subscription_page.rb
- spec/matchers/have_error_messages.rb
- spec/features/subscribe_to_newsletter_spec.rb
- Lightweight matcher with
satisfy
: spec/api/v1/token_spec.rb
See RSpec Rails for installation instructions.
To test a custom validator you've written, refer to these validator specs from other Rails projects. These specs each follow a similar pattern where the validator is tested with a dummy model that is defined and used within the spec only. Using a dummy model is usually preferable to writing a validator spec that is dependent on a real model.
- blacklist_validator_spec.rb from Calagator
- quality_title_validator_spec.rb from Discourse
- phone_number_validator_spec.rb from Netguru-People
- no_empty_spaces_validator_spec.rb from OpenSit
Related task: Demonstrate Validator Specs within rspec-rails-examples