class Minitest::Reporters::MeanTimeReporter
rake reset_statistics
a simple rake task:
(configurable) report. These statistics can be reset at any time by using
file which is parsed at the end of each run to provide a new
This is achieved by creating a (configurable) ‘previous runs’ statistics
3) Provide an abundance of statistics to enjoy.
your tests or algorithms in your code.
2) Identify (and fix) regressions in test run speed caused by changes to
for improvements or refactoring.
1) Identify the slowest running tests over time as potential candidates
allow you to:
maximum times for a test to run. Running this for all your tests will
This reporter creates a report providing the average (mean), minimum and
def self.reset_statistics!
-
(Boolean)
-
def self.reset_statistics! new.reset_statistics! end
def after_suite(suite)
-
(Hash
-Float>)
def after_suite(suite) super @all_suite_times = @suite_times end
def asc?
-
(Boolean)
- Whether the given :order option is :asc.
def asc? order == :asc end
def avg_label
-
(String)
- A yellow 'Avg:' label.
def avg_label ANSI::Code.yellow('Avg:') end
def column_sorted_body
-
(Array
- All of the results sorted byString>>)
def column_sorted_body runs = options[:show_all_runs] ? previous_run : current_run runs.keys.each_with_object([]) do |description, obj| timings = previous_run[description] size = Array(timings).size sum = Array(timings).inject { |total, x| total + x } obj << { avg: (sum / size).round(9), min: Array(timings).min.round(9), max: Array(timings).max.round(9), last: Array(timings).last.round(9), desc: description, } end.sort_by { |k| k[sort_column] } end
def create_new_report!
-
(void)
-
def create_new_report! File.write(report_filename, report_title + report_body) end
def create_or_update_previous_runs!
-
(void)
-
def create_or_update_previous_runs! if previously_ran? current_run.each do |description, elapsed| new_times = if previous_run["#{description}"] Array(previous_run["#{description}"]) << elapsed else Array(elapsed) end previous_run.store("#{description}", new_times) end File.write(previous_runs_filename, previous_run.to_yaml) else File.write(previous_runs_filename, current_run.to_yaml) end end
def current_run
-
(Hash
-Float>)
def current_run Hash[all_suite_times] end
def defaults
-
(Hash)
- Sets default values for the filenames used by this class,
def defaults { order: :desc, show_count: 15, show_progress: true, show_all_runs: true, sort_column: :avg, previous_runs_filename: '/tmp/minitest_reporters_previous_run', report_filename: '/tmp/minitest_reporters_report', } end
def des_label
-
(String)
- A blue 'Description:' label.
def des_label ANSI::Code.blue('Description:') end
def desc?
-
(Boolean)
- Whether the given :order option is :desc (default).
def desc? order == :desc end
def initialize(options = {})
-
(Minitest::Reporters::MeanTimeReporter)
-
Options Hash:
(**order)
-
One
(Symbol
) -- of :desc (default), or :asc. By default the -
One
(Symbol
) -- of :avg (default), :min, :max, :last. -
If
(Boolean
) -- true it shows all recorded suit results. -
If
(Boolean
) -- true it prints pass/skip/fail marks. -
The
(Fixnum
) -- number of tests to show in the report -
Contains
(String
) -- the parsed results for the -
Contains
(String
) -- the times for each test
Parameters:
-
options
(Hash
) --
def initialize(options = {}) super @all_suite_times = [] end
def max_label
-
(String)
- A red 'Max:' label.
def max_label ANSI::Code.red('Max:') end
def min_label
-
(String)
- A green 'Min:' label.
def min_label ANSI::Code.green('Min:') end
def on_record(test)
def on_record(test) super if options[:show_progress] end
def on_report
def on_report super if options[:show_progress] end
def on_start
def on_start super if options[:show_progress] end
def options
-
(Hash)
-
def options defaults.merge!(@options) end
def order
-
(Symbol)
- The :order option, or by default; :desc.
Raises:
-
(Minitest::Reporters::MeanTimeReporter::InvalidOrder)
-
def order orders = [:desc, :asc] if orders.include?(options[:order]) options[:order] else fail Minitest::Reporters::MeanTimeReporter::InvalidOrder, "`:order` option must be one of #{orders.inspect}." end end
def order_sorted_body
-
(String)
- All of the column-sorted results sorted by the :order
def order_sorted_body if desc? column_sorted_body.reverse elsif asc? column_sorted_body end end
def previous_run
-
(Hash
- HashArray ]) Array ]
def previous_run @previous_run ||= YAML.load_file(previous_runs_filename) end
def previous_runs_filename
-
(String)
- The path to the file which contains all the durations
def previous_runs_filename options[:previous_runs_filename] end
def previously_ran?
-
(Boolean)
-
def previously_ran? File.exist?(previous_runs_filename) end
def rate(run, min, max)
-
(Symbol)
- One of :faster, :slower or :inconclusive.
Parameters:
-
max
(Float
) -- The maximum run time. -
min
(Float
) -- The minimum run time. -
run
(Float
) -- The last run time.
def rate(run, min, max) if run == min :faster elsif run == max :slower else :inconclusive end end
def report
terminal.
outputs the parsed results to both the 'report_filename' and the
enhances it by storing the results to the 'previous_runs_filename' and
Runs the {Minitest::Reporters::DefaultReporter#report} method and then
def report super create_or_update_previous_runs! create_new_report! write_to_screen! end
def report_body
-
(String)
-
def report_body order_sorted_body.each_with_object([]) do |result, obj| rating = rate(result[:last], result[:min], result[:max]) obj << "#{avg_label} #{result[:avg].to_s.ljust(12)} " \ "#{min_label} #{result[:min].to_s.ljust(12)} " \ "#{max_label} #{result[:max].to_s.ljust(12)} " \ "#{run_label(rating)} #{result[:last].to_s.ljust(12)} " \ "#{des_label} #{result[:desc]}\n" end.join end
def report_filename
-
(String)
- The path to the file which contains the parsed test
def report_filename options[:report_filename] end
def report_title
-
(String)
-
def report_title "\n\e[4mMinitest Reporters: Mean Time Report\e[24m " \ "(Samples: #{samples}, Order: #{sort_column.inspect} " \ "#{order.inspect})\n" end
def reset_statistics!
-
(void)
-
def reset_statistics! File.open(previous_runs_filename, 'w+') { |f| f.write('') } end
def run_label(rating)
-
(String)
- A purple 'Last:' label.
Parameters:
-
rating
(Symbol
) -- One of :faster, :slower or :inconclusive.
def run_label(rating) case rating when :faster then ANSI::Code.green('Last:') when :slower then ANSI::Code.red('Last:') else ANSI::Code.magenta('Last:') end end
def samples
-
(Fixnum)
-
def samples return 1 unless previous_run.first[1].is_a?(Array) previous_run.first[1].size end
def show_count
-
(Fixnum)
- The number of tests to output to output to the screen
def show_count options[:show_count] end
def sort_column
-
(Symbol)
- The :sort_column option, or by default; :avg.
Raises:
-
(Minitest::Reporters::MeanTimeReporter::InvalidSortColumn)
-
def sort_column sort_columns = [:avg, :min, :max, :last] if sort_columns.include?(options[:sort_column]) options[:sort_column] else fail Minitest::Reporters::MeanTimeReporter::InvalidSortColumn, "`:sort_column` option must be one of #{sort_columns.inspect}." end end
def write_to_screen!
-
(void)
-
def write_to_screen! puts report_title puts report_body.lines.take(show_count) end