Skip to content

Instantly share code, notes, and snippets.

@ryanong
Last active December 22, 2022 16:35
Show Gist options
  • Save ryanong/79f5b76dd30f67a22804b808227c907d to your computer and use it in GitHub Desktop.
Save ryanong/79f5b76dd30f67a22804b808227c907d to your computer and use it in GitHub Desktop.
This will extract any test failures into a separate log file for rspec. Useful for trying to get debug info on large test runs or flakey specs on CI
module LatestTestFailure
class << self
def around(example)
Rails.logger.info start_log(example.location)
example.run
Rails.logger.info end_log(
example.location,
example.exception ? "FAILED" : "PASSED"
)
end
def after_suite
File.write("log/latest_test_failures.log", "")
failed_specs = grep_test_log(end_log(".*", "FAILED"))
failed_specs.each_line do |line|
end_log_line = capture_grep_end_line(line)
start_log_line_number =
grep_test_log(start_log(end_log_line[:spec_location]))
.split(":")
.first
system(
"sed -n " \
"'#{start_log_line_number},#{end_log_line[:number]}p;$a\\\\' " \
"log/test.log " \
">> " \
"log/latest_test_failures.log"
)
end
end
def start_log(location)
"RUN #{run_key} START TEST: #{location}"
end
def end_log(location, pass_fail = nil)
"RUN #{run_key} END TEST: #{location} #{pass_fail}"
end
def capture_grep_end_line(line)
line.match(%r{
(?<number>\d+):
RUN\s(?<run_key>.*)\sEND\sTEST:
\s
(?<spec_location>.*)
\s
(?<pass_fail>PASSED|FAILED)
}x)
end
def grep_test_log(pattern)
`grep -n "#{pattern}" log/test.log`
end
def run_key
@run_key ||= SecureRandom.alphanumeric(5)
end
end
end
RSpec.configure do |config|
config.around do |example|
LatestTestFailure.around(example)
end
config.after(:suite) do
if ENV["CI"] != "0" && ENV["LOG_LATEST_TEST_FAILURE"] != "0"
LatestTestFailure.after_suite
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment