spectre-reporter-vstest 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/spectre/reporter/vstest.rb +171 -0
- metadata +62 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e2969162357e6157b01601d284fceeefc6a591de2c258fb58733bf187424868b
|
4
|
+
data.tar.gz: 2bf7a9b613612ae4da62a679ee3710260a35632cfd44ebe3fd309f62ce948c50
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aad6bb9b517d459de91aa2931b7414ea3057567a8b865d83fec4cfcc2a1ba5a8eb41b45fa06101a97e433b8d57fc7b7910d78bdab74c2dfe9759c1cb77baadb8
|
7
|
+
data.tar.gz: 5e3e6c1eec598c2d0e987589539676c6e580877755c314770dc9931c5f3be494fe5b0af0b30f61371a0ef05b4f119787024683e42b38c20f9da47e2dbfb921a6
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'socket'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
# Azure mappings: https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/test/publish-test-results?view=azure-devops&tabs=trx%2Cyaml
|
6
|
+
|
7
|
+
module Spectre
|
8
|
+
module Reporter
|
9
|
+
class VSTest
|
10
|
+
VERSION = '1.0.0'
|
11
|
+
|
12
|
+
def initialize config
|
13
|
+
@config = config
|
14
|
+
@date_format = '%FT%T.%L'
|
15
|
+
end
|
16
|
+
|
17
|
+
def report run_infos
|
18
|
+
now = Time.now.getutc
|
19
|
+
|
20
|
+
xml_str = '<?xml version="1.0" encoding="UTF-8" ?>'
|
21
|
+
xml_str += %{<TestRun xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">}
|
22
|
+
|
23
|
+
started = run_infos[0].started
|
24
|
+
finished = run_infos[-1].finished
|
25
|
+
|
26
|
+
computer_name = Socket.gethostname
|
27
|
+
|
28
|
+
xml_str += %{<Times start="#{started.strftime(@date_format)}" finish="#{finished.strftime(@date_format)}" />}
|
29
|
+
|
30
|
+
|
31
|
+
# Write summary with file attachments
|
32
|
+
xml_str += '<ResultSummary>'
|
33
|
+
xml_str += '<ResultFiles>'
|
34
|
+
xml_str += %{<ResultFile path="#{File.absolute_path(@config['log_file'])}"></ResultFile>} if File.exists? @config['log_file']
|
35
|
+
|
36
|
+
report_files = Dir[File.join(@config['out_path'], '*')]
|
37
|
+
|
38
|
+
if report_files.any?
|
39
|
+
report_files.each do |report_file|
|
40
|
+
xml_str += %{<ResultFile path="#{File.absolute_path(report_file)}"></ResultFile>}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
xml_str += '</ResultFiles>'
|
45
|
+
xml_str += '</ResultSummary>'
|
46
|
+
|
47
|
+
|
48
|
+
# Write test definitions
|
49
|
+
test_definitions = run_infos
|
50
|
+
.sort_by { |x| x.spec.name }
|
51
|
+
.map { |x| [SecureRandom.uuid(), SecureRandom.uuid(), x] }
|
52
|
+
|
53
|
+
xml_str += '<TestDefinitions>'
|
54
|
+
test_definitions.each do |test_id, execution_id, run_info|
|
55
|
+
xml_str += %{<UnitTest name="#{CGI::escapeHTML get_name(run_info)}" storage="#{CGI::escapeHTML(run_info.spec.file.to_s)}" id="#{test_id}">}
|
56
|
+
xml_str += %{<Execution id="#{execution_id}" />}
|
57
|
+
xml_str += '</UnitTest>'
|
58
|
+
end
|
59
|
+
xml_str += '</TestDefinitions>'
|
60
|
+
|
61
|
+
|
62
|
+
# Write test results
|
63
|
+
xml_str += '<Results>'
|
64
|
+
test_definitions.each do |test_id, execution_id, run_info|
|
65
|
+
duration_str = Time.at(run_info.duration).gmtime.strftime('%T.%L')
|
66
|
+
|
67
|
+
if run_info.failed?
|
68
|
+
outcome = 'Failed'
|
69
|
+
elsif run_info.error?
|
70
|
+
outcome = 'Error'
|
71
|
+
elsif run_info.skipped?
|
72
|
+
outcome = 'Skipped'
|
73
|
+
else
|
74
|
+
outcome = 'Passed'
|
75
|
+
end
|
76
|
+
|
77
|
+
xml_str += %{<UnitTestResult executionId="#{execution_id}" testId="#{test_id}" testName="#{CGI::escapeHTML get_name(run_info)}" computerName="#{computer_name}" duration="#{duration_str}" startTime="#{run_info.started.strftime(@date_format)}" endTime="#{run_info.finished.strftime(@date_format)}" outcome="#{outcome}">}
|
78
|
+
|
79
|
+
if run_info.log.any? or run_info.failed? or run_info.error?
|
80
|
+
xml_str += '<Output>'
|
81
|
+
|
82
|
+
# Write log entries
|
83
|
+
xml_str += '<StdOut>'
|
84
|
+
log_str = ''
|
85
|
+
|
86
|
+
if run_info.properties.count > 0
|
87
|
+
run_info.properties.each do |key, val|
|
88
|
+
log_str += "#{key}: #{val}\n"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
if run_info.data
|
93
|
+
data_str = run_info.data
|
94
|
+
data_str = run_info.data.to_json unless run_info.data.is_a? String or run_info.data.is_a? Integer
|
95
|
+
log_str += "data: #{data_str}\n"
|
96
|
+
end
|
97
|
+
|
98
|
+
run_info.log.each do |timestamp, message, level, name|
|
99
|
+
log_str += %{#{timestamp.strftime(@date_format)} #{level.to_s.upcase} -- #{name}: #{CGI::escapeHTML(message.to_s)}\n}
|
100
|
+
end
|
101
|
+
|
102
|
+
xml_str += log_str
|
103
|
+
xml_str += '</StdOut>'
|
104
|
+
|
105
|
+
# Write error information
|
106
|
+
if run_info.failed? or run_info.error?
|
107
|
+
xml_str += '<ErrorInfo>'
|
108
|
+
|
109
|
+
if run_info.failed? and not run_info.failure.cause
|
110
|
+
xml_str += '<Message>'
|
111
|
+
|
112
|
+
failure_message = "Expected #{run_info.failure.expectation}"
|
113
|
+
failure_message += " with #{run_info.data}" if run_info.data
|
114
|
+
failure_message += " but it failed"
|
115
|
+
failure_message += " with message: #{run_info.failure.message}" if run_info.failure.message
|
116
|
+
|
117
|
+
xml_str += CGI::escapeHTML(failure_message)
|
118
|
+
|
119
|
+
xml_str += '</Message>'
|
120
|
+
end
|
121
|
+
|
122
|
+
if run_info.error or (run_info.failed? and run_info.failure.cause)
|
123
|
+
error = run_info.error || run_info.failure.cause
|
124
|
+
|
125
|
+
failure_message = error.message
|
126
|
+
|
127
|
+
xml_str += '<Message>'
|
128
|
+
xml_str += CGI::escapeHTML(failure_message)
|
129
|
+
xml_str += '</Message>'
|
130
|
+
|
131
|
+
stack_trace = error.backtrace.join "\n"
|
132
|
+
|
133
|
+
xml_str += '<StackTrace>'
|
134
|
+
xml_str += CGI::escapeHTML(stack_trace)
|
135
|
+
xml_str += '</StackTrace>'
|
136
|
+
end
|
137
|
+
|
138
|
+
xml_str += '</ErrorInfo>'
|
139
|
+
end
|
140
|
+
|
141
|
+
xml_str += '</Output>'
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
xml_str += '</UnitTestResult>'
|
146
|
+
end
|
147
|
+
xml_str += '</Results>'
|
148
|
+
|
149
|
+
|
150
|
+
# End report
|
151
|
+
xml_str += '</TestRun>'
|
152
|
+
|
153
|
+
|
154
|
+
Dir.mkdir(@config['out_path']) unless Dir.exists? @config['out_path']
|
155
|
+
|
156
|
+
file_path = File.join(@config['out_path'], "spectre-vstest_#{now.strftime('%s')}.trx")
|
157
|
+
|
158
|
+
File.write(file_path, xml_str)
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def get_name run_info
|
164
|
+
run_name = "[#{run_info.spec.name}] #{run_info.spec.subject.desc}"
|
165
|
+
run_name += " - #{run_info.spec.context.__desc} -" unless run_info.spec.context.__desc.nil?
|
166
|
+
run_name += " #{run_info.spec.desc}"
|
167
|
+
run_name
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spectre-reporter-vstest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christian Neubauer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-08-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: spectre-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
27
|
+
description: Writes a VSTest report for spectre test run, which can be used in Azure
|
28
|
+
DevOps
|
29
|
+
email:
|
30
|
+
- christian.neubauer@ionos.com
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- lib/spectre/reporter/vstest.rb
|
36
|
+
homepage: https://github.com/ionos-spectre/spectre-reporter-vstest
|
37
|
+
licenses:
|
38
|
+
- GPL-3.0-or-later
|
39
|
+
metadata:
|
40
|
+
homepage_uri: https://github.com/ionos-spectre/spectre-reporter-vstest
|
41
|
+
source_code_uri: https://github.com/ionos-spectre/spectre-reporter-vstest
|
42
|
+
changelog_uri: https://github.com/ionos-spectre/spectre-reporter-vstest/blob/master/CHANGELOG.md
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 3.0.0
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubygems_version: 3.3.7
|
59
|
+
signing_key:
|
60
|
+
specification_version: 4
|
61
|
+
summary: A VSTest reporter for spectre
|
62
|
+
test_files: []
|