lupocunit2junit 1.0
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 +7 -0
- data/bin/lupocunit2junit +233 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 65a7e916bfc891a4bcdaeb8d483c3a3a53517a3a
|
4
|
+
data.tar.gz: b127291ca2a8ada6807ed4ad8e67eca9cec07e16
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0b62b482060fa9a62226cfdd2a55add5e31c17c2fa7a2e03453ecc16a7817f41fae08a8ee50ebb1171d7bae79f796c25fc279b7a9627e320be8dd353eaa64eee
|
7
|
+
data.tar.gz: 863e44520c52b237ba7e02c967fff825745e456fec825b772e3e0a05efe96c20c935579e98478203fe8f10ad4b67c313648f170aa14e747a0b46f2f440e87260
|
data/bin/lupocunit2junit
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# ocunit2junit.rb was written by Christian Hedin <christian.hedin@jayway.com>
|
4
|
+
# Version: 0.1 - 30/01 2010
|
5
|
+
# Usage:
|
6
|
+
# xcodebuild -yoursettings | ocunit2junit.rb
|
7
|
+
# All output is just passed through to stdout so you don't miss a thing!
|
8
|
+
# JUnit style XML-report are put in the folder specified below.
|
9
|
+
#
|
10
|
+
# Known problems:
|
11
|
+
# * "Errors" are not cought, only "warnings".
|
12
|
+
# * It's not possible to click links to failed test in Hudson
|
13
|
+
# * It's not possible to browse the source code in Hudson
|
14
|
+
#
|
15
|
+
# Acknowledgement:
|
16
|
+
# Big thanks to Steen Lehmann for prettifying this script.
|
17
|
+
################################################################
|
18
|
+
# Edit these variables to match your system
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# Where to put the XML-files from your unit tests
|
22
|
+
TEST_REPORTS_FOLDER = ENV.has_key?('TEST_REPORTS_FOLDER') ? ENV['TEST_REPORTS_FOLDER'] : "test-reports"
|
23
|
+
SUPPORT_KIWI = ENV.has_key?('SUPPORT_KIWI') ? ENV['SUPPORT_KIWI'] : true
|
24
|
+
#
|
25
|
+
#
|
26
|
+
# Don't edit below this line
|
27
|
+
################################################################
|
28
|
+
|
29
|
+
require 'time'
|
30
|
+
require 'fileutils'
|
31
|
+
require 'socket'
|
32
|
+
|
33
|
+
class ReportParser
|
34
|
+
|
35
|
+
attr_reader :exit_code
|
36
|
+
|
37
|
+
def initialize(piped_input)
|
38
|
+
@piped_input = piped_input
|
39
|
+
@exit_code = 0
|
40
|
+
|
41
|
+
FileUtils.rm_rf(TEST_REPORTS_FOLDER)
|
42
|
+
FileUtils.mkdir_p(TEST_REPORTS_FOLDER)
|
43
|
+
parse_input
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def parse_input
|
49
|
+
if @piped_input.respond_to?(:each)
|
50
|
+
line_enumerator = @piped_input.each
|
51
|
+
elsif @piped_input.respond_to?(:each_line)
|
52
|
+
line_enumerator = @piped_input.each_line
|
53
|
+
end
|
54
|
+
|
55
|
+
line_enumerator.each do |piped_row|
|
56
|
+
if piped_row.respond_to?("encode!")
|
57
|
+
temporary_encoding = (RUBY_VERSION == '1.9.2') ? 'UTF-8' : 'UTF-16'
|
58
|
+
piped_row.encode!(temporary_encoding, 'UTF-8', :invalid => :replace, :replace => '')
|
59
|
+
piped_row.encode!('UTF-8', temporary_encoding)
|
60
|
+
end
|
61
|
+
puts piped_row
|
62
|
+
|
63
|
+
description_results = piped_row.scan(/\s\'(.+)\'\s/)
|
64
|
+
if description_results && description_results[0] && description_results[0]
|
65
|
+
description = description_results[0][0]
|
66
|
+
end
|
67
|
+
|
68
|
+
case piped_row
|
69
|
+
|
70
|
+
when /Test Suite '(\S+)'.*started at\s+(.*)/
|
71
|
+
t = Time.parse($2.to_s)
|
72
|
+
handle_start_test_suite(t)
|
73
|
+
@last_description = nil
|
74
|
+
@current_suite = $1
|
75
|
+
|
76
|
+
when /Test Suite '(\S+)'.*finished at\s+(.*)./
|
77
|
+
t = Time.parse($2.to_s)
|
78
|
+
handle_end_test_suite($1,t)
|
79
|
+
|
80
|
+
when /Test Suite '(\S+)'.*passed at\s+(.*)./
|
81
|
+
t = Time.parse($2.to_s)
|
82
|
+
handle_end_test_suite($1,t)
|
83
|
+
|
84
|
+
when /Test Suite '(\S+)'.*failed at\s+(.*)./
|
85
|
+
t = Time.parse($2.to_s)
|
86
|
+
handle_end_test_suite($1,t)
|
87
|
+
|
88
|
+
when /Test Case '-\[\S+\s+(\S+)\]' started./
|
89
|
+
test_case = $1
|
90
|
+
@last_description = nil
|
91
|
+
@current_test = test_case
|
92
|
+
|
93
|
+
when /Test Case '-\[\S+\s+(\S+)\]' passed \((.*) seconds\)/
|
94
|
+
test_case = get_test_case_name($1, @last_description)
|
95
|
+
test_case_duration = $2.to_f
|
96
|
+
handle_test_passed(test_case,test_case_duration)
|
97
|
+
|
98
|
+
when /Restarting after unexpected exit or crash in (\S+)\//
|
99
|
+
error_message = "Crash encountered during the test!"
|
100
|
+
test_case = @current_test
|
101
|
+
test_suite = @current_suite
|
102
|
+
handle_test_error(test_suite,test_case,error_message, "Search the logs for error location!")
|
103
|
+
#no way to know the time elapsed in this case as XCUnit does not print it in the informational message.
|
104
|
+
handle_test_failed(test_case, 0.000)
|
105
|
+
|
106
|
+
#mark current suite as restarting.
|
107
|
+
@restarting_current_suite = true
|
108
|
+
|
109
|
+
when /(.*): error: -\[(\S+) (\S+)\] : (.*)/
|
110
|
+
error_location = $1
|
111
|
+
test_suite = $2
|
112
|
+
error_message = $4
|
113
|
+
test_case = get_test_case_name($3, description)
|
114
|
+
handle_test_error(test_suite,test_case,error_message,error_location)
|
115
|
+
|
116
|
+
when /Test Case '-\[\S+ (\S+)\]' failed \((\S+) seconds\)/
|
117
|
+
test_case = get_test_case_name($1, @last_description)
|
118
|
+
test_case_duration = $2.to_f
|
119
|
+
handle_test_failed(test_case,test_case_duration)
|
120
|
+
|
121
|
+
when /failed with exit code (\d+)/
|
122
|
+
@exit_code = $1.to_i
|
123
|
+
|
124
|
+
when
|
125
|
+
/BUILD FAILED/
|
126
|
+
@exit_code = -1;
|
127
|
+
end
|
128
|
+
|
129
|
+
if description
|
130
|
+
@last_description = description
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def handle_start_test_suite(start_time)
|
136
|
+
|
137
|
+
#if we detected that XCUinit says it is being restarted because of an unexpected interruption. (i.e. a crash)
|
138
|
+
#In this case, we don't want to treat it as a "newly" encountered suite.
|
139
|
+
return if @restarting_current_suite
|
140
|
+
|
141
|
+
@total_failed_test_cases = 0
|
142
|
+
@total_passed_test_cases = 0
|
143
|
+
@tests_results = Hash.new # test_case -> duration
|
144
|
+
@errors = Hash.new # test_case -> error_msg
|
145
|
+
@ended_current_test_suite = false
|
146
|
+
@cur_start_time = start_time
|
147
|
+
end
|
148
|
+
|
149
|
+
def handle_end_test_suite(test_name,end_time)
|
150
|
+
unless @ended_current_test_suite
|
151
|
+
current_file = File.open("#{TEST_REPORTS_FOLDER}/TEST-#{test_name}.xml", 'w')
|
152
|
+
host_name = string_to_xml Socket.gethostname
|
153
|
+
test_name = string_to_xml test_name
|
154
|
+
test_duration = (end_time - @cur_start_time).to_s
|
155
|
+
total_tests = @total_failed_test_cases + @total_passed_test_cases
|
156
|
+
suite_info = '<testsuite errors="0" failures="'+@total_failed_test_cases.to_s+'" hostname="'+host_name+'" name="'+test_name+'" tests="'+total_tests.to_s+'" time="'+test_duration.to_s+'" timestamp="'+end_time.to_s+'">'
|
157
|
+
current_file << "<?xml version='1.0' encoding='UTF-8' ?>\n"
|
158
|
+
current_file << suite_info
|
159
|
+
@tests_results.each do |t|
|
160
|
+
test_case = string_to_xml t[0]
|
161
|
+
duration = @tests_results[test_case]
|
162
|
+
current_file << "<testcase classname='#{test_name}' name='#{test_case}' time='#{duration.to_s}'"
|
163
|
+
unless @errors[test_case].nil?
|
164
|
+
# uh oh we got a failure
|
165
|
+
puts "tests_errors[0]"
|
166
|
+
puts @errors[test_case][0]
|
167
|
+
puts "tests_errors[1]"
|
168
|
+
puts @errors[test_case][1]
|
169
|
+
|
170
|
+
message = string_to_xml @errors[test_case][0].to_s
|
171
|
+
location = string_to_xml @errors[test_case][1].to_s
|
172
|
+
current_file << ">\n"
|
173
|
+
current_file << "<failure message='#{message}' type='Failure'>#{location}</failure>\n"
|
174
|
+
current_file << "</testcase>\n"
|
175
|
+
else
|
176
|
+
current_file << " />\n"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
current_file << "</testsuite>\n"
|
180
|
+
current_file.close
|
181
|
+
@ended_current_test_suite = true
|
182
|
+
@restarting_current_suite = false
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def string_to_xml(s)
|
187
|
+
s.gsub(/&/, '&').gsub(/'/, '"').gsub(/</, '<')
|
188
|
+
end
|
189
|
+
|
190
|
+
def handle_test_passed(test_case,test_case_duration)
|
191
|
+
@total_passed_test_cases += 1
|
192
|
+
@tests_results[test_case] = test_case_duration
|
193
|
+
end
|
194
|
+
|
195
|
+
def handle_test_error(test_suite,test_case,error_message,error_location)
|
196
|
+
# Only record the first error for a test_case
|
197
|
+
if @errors[test_case].nil?
|
198
|
+
@errors[test_case] = [ error_message, error_location ]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def handle_test_failed(test_case,test_case_duration)
|
203
|
+
@total_failed_test_cases +=1
|
204
|
+
@tests_results[test_case] = test_case_duration
|
205
|
+
end
|
206
|
+
|
207
|
+
def get_test_case_name(test_case, description)
|
208
|
+
# Kiwi 1.x
|
209
|
+
if SUPPORT_KIWI && test_case == "example" && description
|
210
|
+
description
|
211
|
+
# Kiwi 2.x
|
212
|
+
elsif SUPPORT_KIWI && test_case =~ /(.+_)+(Should.+)(_.+)*/
|
213
|
+
test_case.gsub(/([A-Z])([A-Z][a-z]+)/, ' \1 \2')
|
214
|
+
.gsub(/([A-Z][a-z]+)/, ' \1')
|
215
|
+
.gsub(/([A-Z][A-Z]+)/, ' \1')
|
216
|
+
.gsub(/([^A-Za-z ]+)/, ' \1')
|
217
|
+
.gsub(/\s+/, ' ')
|
218
|
+
.split(" _ ")[1..-1].join(", ")
|
219
|
+
.downcase.capitalize
|
220
|
+
else
|
221
|
+
test_case
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
#Main
|
228
|
+
#piped_input = File.open("tests_fail.txt") # for debugging this script
|
229
|
+
piped_input = ARGF.readlines
|
230
|
+
|
231
|
+
report = ReportParser.new(piped_input)
|
232
|
+
|
233
|
+
exit report.exit_code
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lupocunit2junit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christian HedinMichael Lupo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-27 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: 'Simply pipe your xcodebuild output through ocunit2junit: xcodebuild
|
14
|
+
... | lupocunit2junit.rb'
|
15
|
+
email:
|
16
|
+
executables:
|
17
|
+
- lupocunit2junit
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- bin/lupocunit2junit
|
22
|
+
homepage: https://github.com/mikelupo/LUPOCUnit2JUnit
|
23
|
+
licenses: []
|
24
|
+
metadata: {}
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 2.0.14.1
|
42
|
+
signing_key:
|
43
|
+
specification_version: 4
|
44
|
+
summary: A script that converts OCUnit (and Kiwi) output to JUnit style XML output.
|
45
|
+
test_files: []
|