minitest-reporters 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +9 -1
- data/assets/mean_time_reporter.png +0 -0
- data/lib/minitest/reporters/mean_time_reporter.rb +259 -0
- data/lib/minitest/reporters/version.rb +1 -1
- data/test/fixtures/mean_time_test.rb +8 -0
- data/test/integration/reporters/mean_time_reporter_test.rb +7 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 846ef0a08df37769401f230f5de0ecbb833eef54
|
4
|
+
data.tar.gz: 1fd0f582c07365a9524cfd5bfe2462f62fbe67a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ca327e55a81401732fe28cd64b67e7a03e1a4242714556465bed2e9302e95f6c44bbbcc05772bc266e163138913e11f8b039c55e1ea24f8b070db34c33bf219
|
7
|
+
data.tar.gz: 2e765106869fb020d41269e54f170649d3ddc6e657e9f597e429281018ccdb8650ed732911378213d7d9d583318de29b83ca1621a5cf04f97bdfd5bcd9ddc732
|
data/Rakefile
CHANGED
@@ -35,7 +35,8 @@ task :gallery do
|
|
35
35
|
"RubyMateReporter",
|
36
36
|
"SpecReporter",
|
37
37
|
"RubyMineReporter",
|
38
|
-
"HtmlReporter"
|
38
|
+
"HtmlReporter",
|
39
|
+
"MeanTimeReporter",
|
39
40
|
].each do |reporter|
|
40
41
|
puts
|
41
42
|
puts "-" * 72
|
@@ -50,3 +51,10 @@ task :gallery do
|
|
50
51
|
sh "cat test/reports/*" if reporter == "JUnitReporter"
|
51
52
|
end
|
52
53
|
end
|
54
|
+
|
55
|
+
task :reset_statistics do
|
56
|
+
require 'minitest/reporters/mean_time_reporter'
|
57
|
+
Minitest::Reporters::MeanTimeReporter.reset_statistics!
|
58
|
+
puts "The mean time reporter statistics have been reset."
|
59
|
+
exit 0
|
60
|
+
end
|
Binary file
|
@@ -0,0 +1,259 @@
|
|
1
|
+
require 'minitest/reporters'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Minitest
|
5
|
+
module Reporters
|
6
|
+
|
7
|
+
# This reporter creates a report providing the average (mean), minimum and
|
8
|
+
# maximum times for a test to run. Running this for all your tests will
|
9
|
+
# allow you to:
|
10
|
+
#
|
11
|
+
# 1) Identify the slowest running tests over time as potential candidates
|
12
|
+
# for improvements or refactoring.
|
13
|
+
# 2) Identify (and fix) regressions in test run speed caused by changes to
|
14
|
+
# your tests or algorithms in your code.
|
15
|
+
# 3) Provide an abundance of statistics to enjoy.
|
16
|
+
#
|
17
|
+
# This is achieved by creating a (configurable) 'previous runs' statistics
|
18
|
+
# file which is parsed at the end of each run to provide a new
|
19
|
+
# (configurable) report. These statistics can be reset at any time by using
|
20
|
+
# a simple rake task:
|
21
|
+
#
|
22
|
+
# rake reset_statistics
|
23
|
+
#
|
24
|
+
class MeanTimeReporter < Minitest::Reporters::DefaultReporter
|
25
|
+
|
26
|
+
# Reset the statistics file for this reporter. Called via a rake task:
|
27
|
+
#
|
28
|
+
# rake reset_statistics
|
29
|
+
#
|
30
|
+
# @return [Boolean]
|
31
|
+
def self.reset_statistics!
|
32
|
+
new.reset_statistics!
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param options [Hash]
|
36
|
+
# @option previous_runs_filename [String] Contains the times for each test
|
37
|
+
# by description. Defaults to '/tmp/minitest_reporters_previous_run'.
|
38
|
+
# @option report_filename [String] Contains the parsed results for the
|
39
|
+
# last test run. Defaults to '/tmp/minitest_reporters_report'.
|
40
|
+
# @return [Minitest::Reporters::MeanTimeReporter]
|
41
|
+
def initialize(options = {})
|
42
|
+
super
|
43
|
+
|
44
|
+
@all_suite_times = []
|
45
|
+
end
|
46
|
+
|
47
|
+
# Copies the suite times from the
|
48
|
+
# {Minitest::Reporters::DefaultReporter#after_suite} method, making them
|
49
|
+
# available to this class.
|
50
|
+
#
|
51
|
+
# @return [Hash<String => Float>]
|
52
|
+
def after_suite(suite)
|
53
|
+
super
|
54
|
+
|
55
|
+
@all_suite_times = @suite_times
|
56
|
+
end
|
57
|
+
|
58
|
+
# Runs the {Minitest::Reporters::DefaultReporter#report} method and then
|
59
|
+
# enhances it by storing the results to the 'previous_runs_filename' and
|
60
|
+
# outputs the parsed results to both the 'report_filename' and the
|
61
|
+
# terminal.
|
62
|
+
#
|
63
|
+
def report
|
64
|
+
super
|
65
|
+
|
66
|
+
create_or_update_previous_runs!
|
67
|
+
|
68
|
+
create_new_report!
|
69
|
+
|
70
|
+
write_to_screen!
|
71
|
+
end
|
72
|
+
|
73
|
+
# Resets the 'previous runs' file, essentially removing all previous
|
74
|
+
# statistics gathered.
|
75
|
+
#
|
76
|
+
# @return [void]
|
77
|
+
def reset_statistics!
|
78
|
+
File.open(previous_runs_filename, 'w+') { |f| f.write('') }
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
attr_accessor :all_suite_times
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
# @return [Hash<String => Float>]
|
88
|
+
def current_run
|
89
|
+
Hash[all_suite_times]
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [Hash] Sets default values for the filenames used by this class,
|
93
|
+
# and the number of tests to output to output to the screen after each
|
94
|
+
# run.
|
95
|
+
def defaults
|
96
|
+
{
|
97
|
+
count: 15,
|
98
|
+
previous_runs_filename: '/tmp/minitest_reporters_previous_run',
|
99
|
+
report_filename: '/tmp/minitest_reporters_report',
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
# Added to the top of the report file and to the screen output.
|
104
|
+
#
|
105
|
+
# @return [String]
|
106
|
+
def report_title
|
107
|
+
"\n\e[4mMinitest Reporters: Mean Time Report\e[24m (Samples: #{samples})\n"
|
108
|
+
end
|
109
|
+
|
110
|
+
# The report itself. Displays statistics about all runs, ideal for use
|
111
|
+
# with the Unix 'head' command. Listed in slowest average descending
|
112
|
+
# order.
|
113
|
+
#
|
114
|
+
# @return [String]
|
115
|
+
def report_body
|
116
|
+
previous_run.each_with_object([]) do |(description, timings), obj|
|
117
|
+
size = Array(timings).size
|
118
|
+
sum = Array(timings).inject { |total, x| total + x }
|
119
|
+
avg = (sum / size).round(9).to_s.ljust(12)
|
120
|
+
min = Array(timings).min.to_s.ljust(12)
|
121
|
+
max = Array(timings).max.to_s.ljust(12)
|
122
|
+
|
123
|
+
obj << "#{avg_label} #{avg} " \
|
124
|
+
"#{min_label} #{min} " \
|
125
|
+
"#{max_label} #{max} " \
|
126
|
+
"#{des_label} #{description}\n"
|
127
|
+
end.sort.reverse.join
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return [Hash]
|
131
|
+
def options
|
132
|
+
defaults.merge!(@options)
|
133
|
+
end
|
134
|
+
|
135
|
+
# @return [Fixnum] The number of tests to output to output to the screen
|
136
|
+
# after each run.
|
137
|
+
def count
|
138
|
+
options[:count]
|
139
|
+
end
|
140
|
+
|
141
|
+
# @return [Hash<String => Array<Float>]
|
142
|
+
def previous_run
|
143
|
+
@previous_run ||= YAML.load_file(previous_runs_filename)
|
144
|
+
end
|
145
|
+
|
146
|
+
# @return [String] The path to the file which contains all the durations
|
147
|
+
# for each test run. The previous runs file is in YAML format, using the
|
148
|
+
# test name for the key and an array containing the time taken to run
|
149
|
+
# this test for values.
|
150
|
+
def previous_runs_filename
|
151
|
+
options[:previous_runs_filename]
|
152
|
+
end
|
153
|
+
|
154
|
+
# Returns a boolean indicating whether a previous runs file exists.
|
155
|
+
#
|
156
|
+
# @return [Boolean]
|
157
|
+
def previously_ran?
|
158
|
+
File.exist?(previous_runs_filename)
|
159
|
+
end
|
160
|
+
|
161
|
+
# @return [String] The path to the file which contains the parsed test
|
162
|
+
# results. The results file contains a line for each test with the
|
163
|
+
# average time of the test, the minimum time the test took to run,
|
164
|
+
# the maximum time the test took to run and a description of the test
|
165
|
+
# (which is the test name as emitted by Minitest).
|
166
|
+
def report_filename
|
167
|
+
options[:report_filename]
|
168
|
+
end
|
169
|
+
|
170
|
+
# A barbaric way to find out how many runs are in the previous runs file;
|
171
|
+
# this method takes the first test listed, and counts its samples
|
172
|
+
# trusting (naively) all runs to be the same number of samples. This will
|
173
|
+
# produce incorrect averages when new tests are added, so it is advised
|
174
|
+
# to restart the statistics by removing the 'previous runs' file. A rake
|
175
|
+
# task is provided to make this more convenient.
|
176
|
+
#
|
177
|
+
# rake reset_statistics
|
178
|
+
#
|
179
|
+
# @return [Fixnum]
|
180
|
+
def samples
|
181
|
+
return 1 unless previous_run.first[1].is_a?(Array)
|
182
|
+
|
183
|
+
previous_run.first[1].size
|
184
|
+
end
|
185
|
+
|
186
|
+
# Creates a new 'previous runs' file, or updates the existing one with
|
187
|
+
# the latest timings.
|
188
|
+
#
|
189
|
+
# @return [void]
|
190
|
+
def create_or_update_previous_runs!
|
191
|
+
if previously_ran?
|
192
|
+
current_run.each do |description, elapsed|
|
193
|
+
new_times = if previous_run["#{description}"]
|
194
|
+
Array(previous_run["#{description}"]) << elapsed
|
195
|
+
|
196
|
+
else
|
197
|
+
Array(elapsed)
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
previous_run.store("#{description}", new_times)
|
202
|
+
end
|
203
|
+
|
204
|
+
File.write(previous_runs_filename, previous_run.to_yaml)
|
205
|
+
|
206
|
+
else
|
207
|
+
|
208
|
+
File.write(previous_runs_filename, current_run.to_yaml)
|
209
|
+
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Creates a new report file in the 'report_filename'. This file contains
|
214
|
+
# a line for each test of the following example format:
|
215
|
+
#
|
216
|
+
# Avg: 0.0555555 Min: 0.0498765 Max: 0.0612345 Description: The test name
|
217
|
+
#
|
218
|
+
# Note however the timings are to 9 decimal places, and padded to 12
|
219
|
+
# characters and each label is coloured, Avg (yellow), Min (green),
|
220
|
+
# Max (red) and Description (blue). It looks pretty!
|
221
|
+
#
|
222
|
+
# @return [void]
|
223
|
+
def create_new_report!
|
224
|
+
File.write(report_filename, report_title + report_body)
|
225
|
+
end
|
226
|
+
|
227
|
+
# Writes a number of tests (configured via the 'count' option) to the
|
228
|
+
# screen after creating the report. See '#create_new_report!' for example
|
229
|
+
# output information.
|
230
|
+
#
|
231
|
+
# @return [void]
|
232
|
+
def write_to_screen!
|
233
|
+
puts report_title
|
234
|
+
puts report_body.lines.take(count)
|
235
|
+
end
|
236
|
+
|
237
|
+
# @return [String] A yellow 'Avg:' label.
|
238
|
+
def avg_label
|
239
|
+
"\e[33mAvg:\e[39m"
|
240
|
+
end
|
241
|
+
|
242
|
+
# @return [String] A blue 'Description:' label.
|
243
|
+
def des_label
|
244
|
+
"\e[34mDescription:\e[39m"
|
245
|
+
end
|
246
|
+
|
247
|
+
# @return [String] A red 'Max:' label.
|
248
|
+
def max_label
|
249
|
+
"\e[31mMax:\e[39m"
|
250
|
+
end
|
251
|
+
|
252
|
+
# @return [String] A green 'Min:' label.
|
253
|
+
def min_label
|
254
|
+
"\e[32mMin:\e[39m"
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minitest-reporters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Kern
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- README.md
|
111
111
|
- Rakefile
|
112
112
|
- assets/default-reporter.png
|
113
|
+
- assets/mean_time_reporter.png
|
113
114
|
- assets/progress-reporter.png
|
114
115
|
- assets/spec-reporter.png
|
115
116
|
- lib/minitest/extensible_backtrace_filter.rb
|
@@ -122,6 +123,7 @@ files:
|
|
122
123
|
- lib/minitest/reporters/default_reporter.rb
|
123
124
|
- lib/minitest/reporters/html_reporter.rb
|
124
125
|
- lib/minitest/reporters/junit_reporter.rb
|
126
|
+
- lib/minitest/reporters/mean_time_reporter.rb
|
125
127
|
- lib/minitest/reporters/progress_reporter.rb
|
126
128
|
- lib/minitest/reporters/ruby_mate_reporter.rb
|
127
129
|
- lib/minitest/reporters/rubymine_reporter.rb
|
@@ -130,12 +132,14 @@ files:
|
|
130
132
|
- lib/minitest/templates/index.html.erb
|
131
133
|
- minitest-reporters.gemspec
|
132
134
|
- test/fixtures/junit_filename_bug_example_test.rb
|
135
|
+
- test/fixtures/mean_time_test.rb
|
133
136
|
- test/fixtures/progress_detailed_skip_test.rb
|
134
137
|
- test/fixtures/progress_test.rb
|
135
138
|
- test/fixtures/sample_test.rb
|
136
139
|
- test/gallery/bad_test.rb
|
137
140
|
- test/gallery/good_test.rb
|
138
141
|
- test/integration/reporters/junit_reporter_test.rb
|
142
|
+
- test/integration/reporters/mean_time_reporter_test.rb
|
139
143
|
- test/integration/reporters/progress_reporter_test.rb
|
140
144
|
- test/test_helper.rb
|
141
145
|
- test/unit/minitest/extensible_backtrace_filter_test.rb
|
@@ -166,12 +170,14 @@ specification_version: 4
|
|
166
170
|
summary: Create customizable Minitest output formats
|
167
171
|
test_files:
|
168
172
|
- test/fixtures/junit_filename_bug_example_test.rb
|
173
|
+
- test/fixtures/mean_time_test.rb
|
169
174
|
- test/fixtures/progress_detailed_skip_test.rb
|
170
175
|
- test/fixtures/progress_test.rb
|
171
176
|
- test/fixtures/sample_test.rb
|
172
177
|
- test/gallery/bad_test.rb
|
173
178
|
- test/gallery/good_test.rb
|
174
179
|
- test/integration/reporters/junit_reporter_test.rb
|
180
|
+
- test/integration/reporters/mean_time_reporter_test.rb
|
175
181
|
- test/integration/reporters/progress_reporter_test.rb
|
176
182
|
- test/test_helper.rb
|
177
183
|
- test/unit/minitest/extensible_backtrace_filter_test.rb
|