In RSpec, what do --only-failures, --next-failure and --profile each do, and what must spec_helper.rb set before --only-failures works?
answer
- a status file between runs
- example_status_persistence_file_path
- keep it out of version control
- fail-fast plus defined order
- ten slowest by default
basics
~10 s--only-failures reruns just the examples that failed last time and needs config.example_status_persistence_file_path set. --next-failure also stops at the first failure in defined order. --profile reports the slowest examples and groups, ten by default.
solid answer
~40 s`--only-failures` reads each example's last status from the file named by `config.example_status_persistence_file_path` (the template suggests `spec/examples.txt`) and runs only the ones recorded as failed; without that setting rspec aborts with `To use --only-failures, you must first set config.example_status_persistence_file_path`. The file is rewritten after every run with each example's id, status and run time, so it belongs in `.gitignore`. `--next-failure` (`-n`) is shorthand for `--only-failures --fail-fast --order defined`: fix one failure, rerun, move to the next. Either can be combined with a path to limit it to those files. `--profile` (`-p`, or `config.profile_examples`) prints the slowest examples and example groups after the run, 10 of each unless you pass a count such as `--profile 20`.
code
bash · 6 lines$ rspec --only-failures
To use `--only-failures`, you must first set `config.example_status_persistence_file_path`.
# after adding the setting and running the suite once
$ rspec --next-failure # one failure at a time, defined order
$ rspec --profile 5 # 5 slowest examples and groupsgo deeper
Remember that --only-failures reruns what failed last time and that --profile lists the slowest examples.
Explain that --only-failures depends on example_status_persistence_file_path, what the file stores, and that --next-failure adds fail-fast and defined order.
Use these flags to shorten a broken-build loop and read profile output to find slow specs, while keeping the status file out of version control.
Encourage a fast local loop as a team norm, with persistence and profiling in the shared spec_helper, so full-suite runs are for confirmation rather than iteration.
## Remembering results between runs By default rspec forgets everything when it exits. Setting one option in `spec_helper.rb` makes it keep a small status file: ```ruby RSpec.configure do |config| config.example_status_persistence_file_path = "spec/examples.txt" end ``` After each run rspec writes one row per example: its id (such as `./spec/sms_spec.rb[1:2]`), its status (`passed`, `failed`, `pending` or `unknown`) and its run time. Results from the latest run are merged with earlier ones, so examples you did not run this time keep their last known status. The template that `rspec --init` generates suggests this exact line, commented out, and recommends ignoring the file in source control, since every developer's results differ. ## --only-failures `rspec --only-failures` loads the status file and runs only examples recorded as failed: - without the persistence setting it aborts immediately with `To use --only-failures, you must first set config.example_status_persistence_file_path.`; - with a path, as in `rspec spec/services --only-failures`, it runs the previously failed examples among those files; - once everything passes, the file records no failures and the next `--only-failures` run has nothing to do. This turns a slow full-suite failure into a fast loop: run the suite once, then iterate on just what broke. ## --next-failure `--next-failure` (`-n`) is documented as equivalent to `--only-failures --fail-fast --order defined`: 1. it selects the previously failed examples; 2. it runs them in defined order so the sequence is stable; 3. it stops after the first failure. You fix that one, rerun, and it moves on to the next, which keeps the output to a single failure at a time. ## --profile `--profile` (short `-p`, or `config.profile_examples` in configuration) adds a report of slow specs after the run: | Form | Report | |---|---| | `rspec --profile` | the 10 slowest examples and the 10 slowest groups | | `rspec --profile 20` | 20 of each | | `config.profile_examples = 10` | the same as `--profile`, on every run | | `rspec --no-profile` | switches it off for one run | The report is headed `Top 10 slowest examples (... seconds, ...% of total time)`, lists each example's time and location, then does the same for example groups. The rspec-core documentation notes one interaction: with `--fail-fast`, a run that stops on a failure does not print the slow examples. ## What the status file looks like The persistence file is plain text, a padded table that rspec both writes and parses: ``` example_id | status | run_time | ---------------------------- | ------ | --------------- | ./spec/sms_spec.rb[1:1] | passed | 0.00211 seconds | ./spec/sms_spec.rb[1:2] | failed | 0.01302 seconds | ./spec/notifier_spec.rb[1:1] | passed | 0.00087 seconds | ``` A status rspec cannot read is treated as `unknown`. Because ids are positional, adding or moving an example above another can shift ids in that file, and the next `--only-failures` run then targets whatever example now has the old id; a full run refreshes the table. ## Putting them together A typical local loop after a broken build: 1. `rspec` once, with persistence on, to record statuses; 2. `rspec --next-failure` repeatedly until it reports no failures; 3. `rspec` again to confirm the whole suite; 4. `rspec --profile` occasionally to see which specs make the loop slow. ## Common mistakes - Expecting `--only-failures` to work on a fresh `rspec --init` project: the persistence line is commented out. - Committing `spec/examples.txt`, which causes merge noise and applies one person's failures to everyone. - Treating `--profile` output as a benchmark: it measures one run, including setup noise, and is a pointer, not a measurement.
- Why should spec/examples.txt be ignored by version control?rspec rewrites it after every run with that machine's example statuses and run times. Committed, it produces constant diffs and hands one developer's failures to everyone who pulls, so their `--only-failures` runs the wrong examples. The generated `spec_helper.rb` comment recommends ignoring it for that reason.
- When does --profile not show its report?The rspec-core documentation says that when `--fail-fast` is combined with `--profile` and a failure stops the run, the slow examples are not shown. Profile a passing run, or drop `--fail-fast`, when you need the report.
saying these in an interview costs you the question
- --only-failures works out of the box after rspec --init
- --next-failure runs failures in random order
- the status file should be committed so CI knows what failed
- --profile prints the slowest 5 examples by default
- --only-failures reruns failures from CI without any local file