Skip to content

Instantly share code, notes, and snippets.

@brainwire
Created February 26, 2016 07:03
Show Gist options
  • Save brainwire/ffa7c23ee71caefc5588 to your computer and use it in GitHub Desktop.
Save brainwire/ffa7c23ee71caefc5588 to your computer and use it in GitHub Desktop.
rspec retry mechanism
describe 'my fake tests', :type => :feature do
it 'this scenario should pass' do
expect(true).to eq true
end
it 'this scenario should fail' do
expect(false).to eq true
end
end
require 'fileutils'
require 'childprocess'
task :rspec_with_retries, [:max_tries] do |_, args|
max_tries = args[:max_tries].to_i
# exit hook to ensure rspec process gets stopped when CTRL+C (SIGTERM is pressed)
# needs to be set outside the times loop as otherwise each iteration would add its
# own at_exit hook
process = nil
at_exit do
process.stop unless process.nil?
end
# construct initial rspec command
command = ['bundle', 'exec', 'rspec', '--require', './spec/formatters/failure_formatter.rb', '--format', 'FailureFormatter', '--no-fail-fast']
max_tries.times do |t|
puts "\n"
puts '##########'
puts "### STARTING TEST RUN #{t + 1} OUT OF A MAXIMUM OF #{max_tries}"
puts "### executing command: #{command}"
puts '##########'
# delete tests_failed file left over by previous run
FileUtils.rm('tests_failed', :force => true)
# run tests in separate process
process = ChildProcess.build(*command)
process.io.inherit!
process.start
process.wait
# early out
exit 0 if process.exit_code.zero?
exit 1 if (t == max_tries - 1)
# determine which tests need to be run again
failed_tests = []
File.open('tests_failed', 'r') do |file|
failed_tests = file.readlines.map { |line| line.strip }
end
# construct command to rerun just the failed tests
command = ['bundle', 'exec', 'rspec']
command += Array.new(failed_tests.length, '-e').zip(failed_tests).flatten
command += ['--require', './spec/formatters/failure_formatter.rb', '--format', 'FailureFormatter', '--no-fail-fast']
end
end
require 'rspec/core/formatters/progress_formatter'
class FailureFormatter < RSpec::Core::Formatters::ProgressFormatter
RSpec::Core::Formatters.register self, :example_failed
def example_failed(notification)
super
File.open('tests_failed', 'a') do |file|
file.puts(notification.example.full_description)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment