Since I've already written an article about how to run parallel Rails tests on Heroku CI, I wanted to share how to do it on Github Actions.
Here's a simple way to partition your tests, without using third party services.
# .github/workflows/test.yml
---
name: Test
on: [push]
jobs:
tests:
name: Tests
runs-on: ubuntu-latest
strategy:
matrix:
# Specify an index for each job ran in parallel
index: [0, 1, 2, 3, 4]
steps:
# ...
- name: Run tests
env:
# Specifies how many jobs you would like to run in parallel,
# used for partitioning
NUMBER_OF_NODES: 5
# Use the index from matrix as an environment variable
CI_NODE_INDEX: ${{ matrix.index }}
run: |
./bin/test
This will run 5 jobs in parallel and it assumes you have a
./bin/test
script for partitioning your tests.
This is how that script looks like:
#!/usr/bin/env ruby
tests = Dir["test/**/*_test.rb"].
# Add some randomization. Different test order for every run.
shuffle(random: Random.new(ENV["GITHUB_RUN_ID"])).
select.
with_index do |_, i|
i % ENV["NUMBER_OF_NODES"].to_i == ENV["CI_NODE_INDEX"].to_i
end
exec "bundle exec rails test #{tests.join(" ")}"
The script assumes you are using Minitest, so replace the rails test
with rspec
and
update the test lookup bit if you're using RSpec.
The downside of this approach is that your tests will not be split based on the duration of tests, so some jobs might take longer than others.