Last active
March 31, 2019 03:45
-
-
Save kirkelifson/b4054457fb583f5771e91613d1cef14c to your computer and use it in GitHub Desktop.
rspec all day - simple test runner for finding fragile tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'json' | |
require 'awesome_print' | |
require 'colorize' | |
class SpecRunner | |
FILE_NAME = "spec_run_#{Time.now.strftime("%H%M%S_%m%d%y_%Z")}.log" | |
TEST_LOG_FILE = 'log/test.log'.freeze | |
LOG_FILE_SIZE_LIMIT = 500 | |
attr_reader :results, :summary, :failure_count | |
def new | |
@results = nil | |
@summary = nil | |
@failure_count = 0 | |
@duration = 0 | |
end | |
def run | |
@results ||= parse_results(rspec) | |
@summary ||= summarize | |
@failure_count = @summary['failures'] || @summary['failure'] || 0 | |
@duration = @results.dig('summary', 'duration').round | |
log_failures if @failure_count.nonzero? | |
scrub_rails_log if log_reached_size_limit? | |
print_run_time | |
end | |
def rspec | |
`NO_COVERAGE=true rspec -fj #{ARGV.join(' ')} 2> /dev/null` | |
end | |
def parse_results(output) | |
JSON.parse(output) | |
rescue JSON::ParserError | |
puts '[!] Could not parse rspec JSON output, exiting'.red | |
exit | |
end | |
def summarize | |
keys = [] | |
summary_line = @results['summary_line'].split(',').map do |result| | |
result.strip! | |
keys << result[/[a-z]+/] | |
result[/\d+/].to_i | |
end | |
[keys, summary_line].transpose.to_h | |
end | |
def log_failures | |
failures = @results['examples'].select do |example| | |
example['status'] == 'failed' | |
end | |
open(FILE_NAME, 'a') do |file| | |
puts "[!] Logging #{failure_count} failures".red | |
file.puts(@results) | |
end | |
puts failures.map { |failure| "\t#{failure['id']}\n" } | |
end | |
def log_size | |
File.size(TEST_LOG_FILE) / 2**20 | |
end | |
def log_reached_size_limit? | |
log_size > LOG_FILE_SIZE_LIMIT | |
end | |
def scrub_rails_log | |
puts '[+] Cleaning up test log files'.yellow | |
File.delete(TEST_LOG_FILE) | |
end | |
def print_run_time | |
puts "Run time: #{@duration} seconds, #{(@duration / 60.0).round(2)} minutes\n\n" | |
end | |
end | |
def shutdown | |
puts '[+] Shutting down gracefully'.yellow | |
$running = false | |
end | |
trap("INT") { shutdown } | |
def clean_database | |
puts '[+] Starting reset of the test database' | |
`RAILS_ENV=test rake db:schema:load 2> /dev/null` | |
puts '[+] Reset the test database'.green | |
end | |
$running = true | |
$iteration = 1 | |
def run | |
begin | |
runner = SpecRunner.new | |
puts "[+] Started rspec run ##{$iteration}" | |
runner.run | |
puts "[+] Finished rspec run ##{$iteration}".green | |
$iteration += 1 | |
rescue SystemExit, Interrupt | |
end | |
end | |
clean_database | |
run while $running |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment