Different ways to run RSpec tests

RSpec is a popular testing framework for Ruby. While running all tests with bundle exec rspec is common, RSpec offers several ways to run specific tests more efficiently. This post covers various methods to target and execute particular tests.

Running tests by file path

Instead of running all tests, you can specify a file or directory path to run specific tests:

# Run all tests in a specific file
bundle exec rspec spec/models/user_spec.rb

# Run all tests in a directory and its subdirectories
bundle exec rspec spec/models/

# Run all tests matching a file pattern (the -P option allows using glob patterns)
bundle exec rspec -P spec/**/user*_spec.rb

Running tests by line number

To run a specific test, RSpec allows you to specify the file path and line number:

# Run the test at line 42 in user_spec.rb
bundle exec rspec spec/models/user_spec.rb:42

Running tests by description

Since line numbers may change when editing spec files, a more stable approach is to run tests by description using the --example option (or -e for short):

# Run all tests with descriptions containing "user authentication"
bundle exec rspec --example "user authentication"

Running tests with specific tags

You can tag your tests and run specific tagged examples. Tags are metadata that you can add to your tests after the description. This is useful for grouping and filtering tests.

# In your test file
it "does something", :focus do
  # test code
end

# Run only focused tests
bundle exec rspec --tag focus

# Run all tests except those tagged with :slow
bundle exec rspec --tag ~slow

Tags can also have assigned values:

# In your test file
it "does something", feature: :checkout do
  # test code
end

# Run all tests related to checkout feature. `-t` is short for `--tag`.
bundle exec rspec -t feature:checkout

Focus mode with fit, fdescribe, or fcontext

Focus mode allows you to run only specific tests, which is particularly useful during development or debugging. To use it, you need to tag the test examples or groups you care about with :focus metadata. When nothing is tagged with :focus, all examples get run. RSpec provides aliases for it, describe, and context that include :focus metadata: fit, fdescribe, and fcontext, respectively.

# Only this test will run
fit "validates user email" do
  # test code
end

# Only tests in this describe block will run
fdescribe "User authentication" do
  it "validates password" do
    # test code
  end
end

# Only tests in this context block will run
fcontext "when authentication succeeds" do
  it "redirects user to home page" do
    # test code
  end
end

Note

Remember to remove fit, fdescribe, and fcontext before committing your code! If you use Rubocop, it will remember you to remove them too.

Running failed tests

To run only the failed tests after a refactoring or merging recent changes, use the --only-failures option:

# Run all tests that failed the last time they ran
bundle exec rspec --only-failures

To enable this feature, add the following to your spec_helper.rb to allow RSpec to track failed tests:

RSpec.configure do |config|
  config.example_status_persistence_file_path = "spec/examples.txt"
end

This feature is particularly useful when you have a large test suite and want to focus on fixing recent failures.

If you have many failing tests or prefer to focus on fixing one failure at a time, use the --next-failure option (or -n for short) to run only the next failed test.

Conclusion

These different methods of running tests can significantly improve the testing workflow, allowing you to focus on relevant tests while debugging or developing new features.