Skip to content

Instantly share code, notes, and snippets.

@aaronhumerickhouse
Last active August 29, 2015 14:07
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 aaronhumerickhouse/80f06da79de12ec3b4e2 to your computer and use it in GitHub Desktop.
Save aaronhumerickhouse/80f06da79de12ec3b4e2 to your computer and use it in GitHub Desktop.
Parallel execution for RSpec and Browserstack
desc 'Runs Selenium Tests in browserstack in parallel'
task :browserstack_spec_parallel, [:opts] do |t, args|
puts "Running with: #{@browser.inspect}"
setup_browserstack_variables(@browser)
begin
# Get all files
pattern = args[:opts].split('--pattern')[-1].split(' ')[0].gsub('"', '')
test_files = FileList[pattern].shuffle
# Slice the test files to evenly distribute amongst forks
test_files_sliced = test_files.each_slice(test_files.length / @forks).to_a
#Adjust for slices with remainders
if test_files.length % @forks != 0
test_files_sliced = adjust_slices(test_files_sliced)
end
pids = []
@forks.times do |i|
pids << fork do
begin
puts "Fork #{i} testing #{test_files_sliced[i].join(", ")}"
#Setup unique job
RSpec::Core::RakeTask.new("spec#{i}", :opts) do |t, args|
t.rspec_opts = strip_quotes(args)
end
# Adjust Options, remove pattern for unique job
opts = remove_pattern(args[:opts])
opts = strip_quotes(opts)
if opts.include? 'rspec_results.html'
opts = opts.gsub('rspec_results.html', "rspec_results[#{i}].html")
end
#Add files to rspec args
test_files_sliced[i].each { |file|
opts = opts << " #{file.to_s}"
}
sio = redirect_stdout
# Run the test
Rake::Task["spec#{i}"].execute(opts)
rescue => ex
sio << "\n#{ex.message}\n#{ex.backtrace.join("\t\n")}"
ensure
# reset stdout
$stdout = STDOUT
# Output the test results
puts "Fork #{i} completed, output:"
puts "Testing:\n#{test_files_sliced[i].join(", ")}\n"
sio.rewind
puts sio.read
# Force the fork to end without running at_exit bindings
Kernel.exit!
end
end
end
Process.waitall
rescue => e
puts e.message
puts e.backtrace.join("\n\t")
end
end
#------ rake/utilities.rb ----------
def redirect_stdout
sio = StringIO.new
$stdout = sio
$stderr = sio
return sio
end
def adjust_slices(test_files_sliced)
test_files_sliced[0] << test_files_sliced[-1]
return test_files_sliced[0..test_files_sliced.size-2]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment