Skip to content

Instantly share code, notes, and snippets.

@brand-it
Created January 30, 2019 16:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brand-it/4c412b346c58b61b035f1645218217a5 to your computer and use it in GitHub Desktop.
Save brand-it/4c412b346c58b61b035f1645218217a5 to your computer and use it in GitHub Desktop.
Grouping Rspec Tests
#!/usr/bin/env ruby
require 'optparse'
options = { group: 0, total_groups: 0, pattern: 'spec/**/*_spec.rb' }
OptionParser.new do |opts|
opts.banner = "Usage: bin/rspec [options]"
opts.on('-t', '--total-groups NUMBER', 'Total number of rspec groups') do |t|
options[:total_groups] = t.to_i
end
opts.on('-g', '--group NUMBER', 'Execute group number out of total groups') do |g|
options[:group] = g.to_i
end
opts.on('-p' '--pattern spec/**/*_spec.rb', 'The pattern used to find the rspec files') do |p|
options[:pattern] = p
end
opts.on('-r' '--rspec-options', 'Options that you want to pass to rspec') do |r|
end
end.parse!
if options[:group].to_i <= 0
puts 'group has to be greater than zero'
exit
end
if options[:group] > options[:total_groups]
puts 'group has to be less than or equal to total groups'
exit
end
groups = Array.new(options[:total_groups]) { { total: 0, tests: [] } }
files = Dir[options[:pattern]].sort { |a, z| File.stat(a).size <=> File.stat(z).size }
index = 0
while files.size > 0
groups[index][:tests] << files.pop
groups[index][:total] += 1
index += 1
index = 0 if index >= groups.size
end
group = groups[options[:group] - 1]
puts group
if group[:total].zero?
puts "There are no tests for group #{options[:group]}"
exit 0
end
puts "Executing rspec: #{group[:total]} in group #{options[:group]} of #{options[:total_groups]}"
if system("bin/bundle exec rspec #{group[:tests].join(' ')} -f progress --color --tty")
exit 0
else
exit 1
end
@brand-it
Copy link
Author

brand-it commented Jan 30, 2019

Usage of this script.

grouping_rspec_test --total-groups 5 --group 1
grouping_rspec_test --total-groups 5 --group 2
grouping_rspec_test --total-groups 5 --group 3
grouping_rspec_test --total-groups 5 --group 4
grouping_rspec_test --total-groups 5 --group 5

@brand-it
Copy link
Author

The script takes into account also the size of test files and tries to keep the total groups of each RSpec test file equal. This helps with not having one group taking much longer than the rest as the work should be more distributed. This script is not a recommended replacement to some of the other parallel tools out there however it is nice if you just need something quick and dirty to get the job done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment