minitest-reporters 1.3.6 → 1.3.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +28 -27
- data/.rubocop.yml +77 -77
- data/.ruby-gemset +1 -1
- data/.travis.yml +14 -14
- data/.yardopts +5 -5
- data/CHANGELOG.md +102 -93
- data/Gemfile +2 -2
- data/LICENSE +20 -20
- data/README.md +135 -135
- data/Rakefile +70 -70
- data/appveyor.yml +22 -22
- data/lib/minitest/extensible_backtrace_filter.rb +67 -67
- data/lib/minitest/minitest_reporter_plugin.rb +76 -76
- data/lib/minitest/old_activesupport_fix.rb +24 -24
- data/lib/minitest/relative_position.rb +26 -26
- data/lib/minitest/reporters/ansi.rb +30 -30
- data/lib/minitest/reporters/base_reporter.rb +136 -136
- data/lib/minitest/reporters/default_reporter.rb +228 -228
- data/lib/minitest/reporters/html_reporter.rb +224 -224
- data/lib/minitest/reporters/junit_reporter.rb +168 -164
- data/lib/minitest/reporters/mean_time_reporter.rb +388 -388
- data/lib/minitest/reporters/progress_reporter.rb +104 -96
- data/lib/minitest/reporters/ruby_mate_reporter.rb +54 -54
- data/lib/minitest/reporters/rubymine_reporter.rb +116 -116
- data/lib/minitest/reporters/spec_reporter.rb +61 -61
- data/lib/minitest/reporters/version.rb +5 -5
- data/lib/minitest/reporters.rb +91 -91
- data/lib/minitest/templates/index.html.erb +82 -82
- data/minitest-reporters.gemspec +31 -32
- data/test/fixtures/junit_filename_bug_example_test.rb +41 -41
- data/test/fixtures/mean_time_test.rb +36 -36
- data/test/fixtures/progress_detailed_skip_test.rb +8 -8
- data/test/fixtures/progress_test.rb +8 -8
- data/test/fixtures/sample_test.rb +15 -15
- data/test/fixtures/spec_test.rb +18 -18
- data/test/gallery/bad_test.rb +25 -25
- data/test/gallery/good_test.rb +14 -14
- data/test/integration/reporters/junit_reporter_test.rb +12 -12
- data/test/integration/reporters/mean_time_reporter_test.rb +7 -7
- data/test/integration/reporters/progress_reporter_test.rb +40 -40
- data/test/test_helper.rb +22 -22
- data/test/unit/minitest/extensible_backtrace_filter_test.rb +42 -42
- data/test/unit/minitest/junit_reporter_test.rb +46 -23
- data/test/unit/minitest/mean_time_reporter_unit_test.rb +149 -149
- data/test/unit/minitest/minitest_reporter_plugin_test.rb +14 -14
- data/test/unit/minitest/reporters_test.rb +65 -65
- data/test/unit/minitest/spec_reporter_test.rb +62 -62
- metadata +22 -5
@@ -1,164 +1,168 @@
|
|
1
|
-
require 'builder'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'pathname'
|
4
|
-
module Minitest
|
5
|
-
module Reporters
|
6
|
-
# A reporter for writing JUnit test reports
|
7
|
-
# Intended for easy integration with CI servers - tested on JetBrains TeamCity
|
8
|
-
#
|
9
|
-
# Inspired by ci_reporter (see https://github.com/nicksieger/ci_reporter)
|
10
|
-
# Also inspired by Marc Seeger's attempt at producing a JUnitReporter (see https://github.com/rb2k/minitest-reporters/commit/e13d95b5f884453a9c77f62bc5cba3fa1df30ef5)
|
11
|
-
# Also inspired by minitest-ci (see https://github.com/bhenderson/minitest-ci)
|
12
|
-
class JUnitReporter < BaseReporter
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
elsif test.
|
107
|
-
xml.
|
108
|
-
xml.text!(message_for(test))
|
109
|
-
end
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
elsif test.
|
125
|
-
"
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
1
|
+
require 'builder'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'pathname'
|
4
|
+
module Minitest
|
5
|
+
module Reporters
|
6
|
+
# A reporter for writing JUnit test reports
|
7
|
+
# Intended for easy integration with CI servers - tested on JetBrains TeamCity
|
8
|
+
#
|
9
|
+
# Inspired by ci_reporter (see https://github.com/nicksieger/ci_reporter)
|
10
|
+
# Also inspired by Marc Seeger's attempt at producing a JUnitReporter (see https://github.com/rb2k/minitest-reporters/commit/e13d95b5f884453a9c77f62bc5cba3fa1df30ef5)
|
11
|
+
# Also inspired by minitest-ci (see https://github.com/bhenderson/minitest-ci)
|
12
|
+
class JUnitReporter < BaseReporter
|
13
|
+
DEFAULT_REPORTS_DIR = "test/reports".freeze
|
14
|
+
|
15
|
+
attr_reader :reports_path
|
16
|
+
|
17
|
+
def initialize(reports_dir = DEFAULT_REPORTS_DIR, empty = true, options = {})
|
18
|
+
super({})
|
19
|
+
@reports_path = File.absolute_path(ENV.fetch("MINITEST_REPORTERS_REPORTS_DIR", reports_dir))
|
20
|
+
@single_file = options[:single_file]
|
21
|
+
@base_path = options[:base_path] || Dir.pwd
|
22
|
+
|
23
|
+
if empty
|
24
|
+
puts "Emptying #{@reports_path}"
|
25
|
+
FileUtils.mkdir_p(@reports_path)
|
26
|
+
File.delete(*Dir.glob("#{@reports_path}/TEST-*.xml"))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def report
|
31
|
+
super
|
32
|
+
|
33
|
+
puts "Writing XML reports to #{@reports_path}"
|
34
|
+
suites = tests.group_by { |test|
|
35
|
+
test_class(test)
|
36
|
+
}
|
37
|
+
|
38
|
+
if @single_file
|
39
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
40
|
+
xml.instruct!
|
41
|
+
xml.testsuites do
|
42
|
+
suites.each do |suite, tests|
|
43
|
+
parse_xml_for(xml, suite, tests)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
File.open(filename_for('minitest'), "w") { |file| file << xml.target! }
|
47
|
+
else
|
48
|
+
suites.each do |suite, tests|
|
49
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
50
|
+
xml.instruct!
|
51
|
+
xml.testsuites do
|
52
|
+
parse_xml_for(xml, suite, tests)
|
53
|
+
end
|
54
|
+
File.open(filename_for(suite), "w") { |file| file << xml.target! }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_relative_path(result)
|
60
|
+
file_path = Pathname.new(get_source_location(result).first)
|
61
|
+
base_path = Pathname.new(@base_path)
|
62
|
+
file_path.relative_path_from(base_path) if file_path.absolute?
|
63
|
+
file_path
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def get_source_location(result)
|
69
|
+
if result.respond_to? :klass
|
70
|
+
result.source_location
|
71
|
+
else
|
72
|
+
result.method(result.name).source_location
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_xml_for(xml, suite, tests)
|
77
|
+
suite_result = analyze_suite(tests)
|
78
|
+
file_path = get_relative_path(tests.first)
|
79
|
+
|
80
|
+
xml.testsuite(:name => suite, :filepath => file_path,
|
81
|
+
:skipped => suite_result[:skip_count], :failures => suite_result[:fail_count],
|
82
|
+
:errors => suite_result[:error_count], :tests => suite_result[:test_count],
|
83
|
+
:assertions => suite_result[:assertion_count], :time => suite_result[:time]) do
|
84
|
+
tests.each do |test|
|
85
|
+
lineno = get_source_location(test).last
|
86
|
+
xml.testcase(:name => test.name, :lineno => lineno, :classname => suite, :assertions => test.assertions,
|
87
|
+
:time => test.time) do
|
88
|
+
xml << xml_message_for(test) unless test.passed?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def xml_message_for(test)
|
95
|
+
# This is a trick lifted from ci_reporter
|
96
|
+
xml = Builder::XmlMarkup.new(:indent => 2, :margin => 2)
|
97
|
+
|
98
|
+
def xml.trunc!(txt)
|
99
|
+
txt.sub(/\n.*/m, '...')
|
100
|
+
end
|
101
|
+
|
102
|
+
e = test.failure
|
103
|
+
|
104
|
+
if test.skipped?
|
105
|
+
xml.skipped(:type => test.name)
|
106
|
+
elsif test.error?
|
107
|
+
xml.error(:type => test.name, :message => xml.trunc!(e.message)) do
|
108
|
+
xml.text!(message_for(test))
|
109
|
+
end
|
110
|
+
elsif test.failure
|
111
|
+
xml.failure(:type => test.name, :message => xml.trunc!(e.message)) do
|
112
|
+
xml.text!(message_for(test))
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def message_for(test)
|
118
|
+
suite = test.class
|
119
|
+
name = test.name
|
120
|
+
e = test.failure
|
121
|
+
|
122
|
+
if test.passed?
|
123
|
+
nil
|
124
|
+
elsif test.skipped?
|
125
|
+
"Skipped:\n#{name}(#{suite}) [#{location(e)}]:\n#{e.message}\n"
|
126
|
+
elsif test.failure
|
127
|
+
"Failure:\n#{name}(#{suite}) [#{location(e)}]:\n#{e.message}\n"
|
128
|
+
elsif test.error?
|
129
|
+
"Error:\n#{name}(#{suite}):\n#{e.message}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def location(exception)
|
134
|
+
last_before_assertion = ''
|
135
|
+
exception.backtrace.reverse_each do |s|
|
136
|
+
break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
|
137
|
+
last_before_assertion = s
|
138
|
+
end
|
139
|
+
last_before_assertion.sub(/:in .*$/, '')
|
140
|
+
end
|
141
|
+
|
142
|
+
def analyze_suite(tests)
|
143
|
+
result = Hash.new(0)
|
144
|
+
result[:time] = 0
|
145
|
+
tests.each do |test|
|
146
|
+
result[:"#{result(test)}_count"] += 1
|
147
|
+
result[:assertion_count] += test.assertions
|
148
|
+
result[:test_count] += 1
|
149
|
+
result[:time] += test.time
|
150
|
+
end
|
151
|
+
result
|
152
|
+
end
|
153
|
+
|
154
|
+
def filename_for(suite)
|
155
|
+
file_counter = 0
|
156
|
+
# restrict max filename length, to be kind to filesystems
|
157
|
+
suite_name = suite.to_s[0..240].gsub(/[^a-zA-Z0-9]+/, '-')
|
158
|
+
filename = "TEST-#{suite_name}.xml"
|
159
|
+
while File.exist?(File.join(@reports_path, filename)) # restrict number of tries, to avoid infinite loops
|
160
|
+
file_counter += 1
|
161
|
+
filename = "TEST-#{suite_name}-#{file_counter}.xml"
|
162
|
+
puts "Too many duplicate files, overwriting earlier report #{filename}" and break if file_counter >= 99
|
163
|
+
end
|
164
|
+
File.join(@reports_path, filename)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|