I always do my best to run tests on my local machine before publishing a PR. However, depending on the size of the test base, this could be unsustainable.
To solve this, I at least run the tests on all *_spec.rb
files of my current working branch (or stack of branches) that were changed (or created) since another branch. Usually, it’s main or staging.
Let’s look at the code below:
o feature-2/more-features
| changed file: user_spec.rb
o bugfix/fix-users-controller-params
| created file: users_controller_spec.rb
o feature-1/branch-1-new-feature
| updated file: product_spec.rb
| updated file: new_payment_service_spec.rb
o main
This is a purely didactic example
This stack of branches has changed/created 4 spec files. Now, I want to run RSpec on only those four files, not on the entire test base.
To achieve this goal, I created a bash script to use git to list all changed *_spec.rb
files and run the rspec
command against them. Here is the code:
#!/bin/bash
# Set default branch name
branch_name="${1:-staging}"
# Get changed files with grep for _spec.rb extension
changed_specs=$(git diff --name-only --diff-filter=d "$branch_name" | grep _spec.rb)
# Check if any changed specs found
if [[ -z "$changed_specs" ]]; then
echo "No changed _spec.rb files found between HEAD and $branch_name."
exit 0
fi
echo "List of changed spec files:"
echo "$changed_specs"
# Run rspec with all changed specs
bundle exec rspec $changed_specs
echo "RSpec tests completed for changed _spec.rb files."
Click here to view and download this gist
Save this file and give it a name (I use rspec_changed_files.sh
).
Now, simply run it on your repo directory.
./rspec_changed_files.sh
By default, it will find the changed files related to the staging
branch, but you can adapt the code or override the branch on the command line with another branch name or commit hash:
./rspec_changed_files.sh main
Output:
List of changed spec files:
spec/models/user_spec.rb
spec/controllers/users_controller_spec.rb
spec/models/product_spec.rb
spec/services/new_payment_service_spec.rb
....................
Finished in 0.60517 seconds (files took 1.81 seconds to load)
10 examples, 0 failures
RSpec tests completed for changed _spec.rb files.
Happy testing!
Top comments (2)
This is not quite what you want to do. What you need is to run all the tests that deal with the code that you have changed, not just the tests that have changed. There are existing tools for this - pronto can tell you which files have changed, guard will run tests as you change them, and there is an amazing gem github.com/toptal/crystalball which does exactly the behaviour I suggested above. But really you should run all the tests - if they are impractical to run locally, then maybe your project should invest some time in fixing that.?
Hi Stephen. Thanks for the tip for Crystalball. I'll give it a try.