testrail_rspec 0.0.1 → 0.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 892fde2a276a04d5eb848babfe6f5d55f890bc46
4
- data.tar.gz: 1367fdb75da3e603bf8ca11ba3bdecf825917d63
3
+ metadata.gz: 17b37cac0d137dcd55f241b808e8ba02fa234a07
4
+ data.tar.gz: 5891b2058f8bf42d9d925a51262de4a18e9c89ae
5
5
  SHA512:
6
- metadata.gz: f13bbde2db33c79f2f593f971c81190403e5b5d513a5b4d93fc4c143389dadcdd1b775a60a9b7052a4a34c5cf401a5a258e87dba570a27970d021c762ba3f19a
7
- data.tar.gz: 8a780a95af0e588b3ad66ca7e932a384954d298b72c6be55a005e2e8ed6ccea14f831ebd6d24cad33fae59c2f6a504dcbe21787c6c944a932de1ff3bd206d975
6
+ metadata.gz: d4c0abc08cc139acc854f1d176f8fde321eb793dd2c882fec3523a52b71d13ac38022f2f1d910f7d5168969b4dbcf4727b6dc976f44eacc1e4b3266284e10faa
7
+ data.tar.gz: 21bea9900fd213c483d0634ace6a3d393aa1868437f6fc33617a32ab0dd59dd3a9d816723ccf0fb46e3a900a18f155671d2afe8a33dd82cc4a0c11a7a071730f
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Testrail::Rspec
1
+ # TestrailRspec
2
2
 
3
3
  This gem provides custom RSpec formatter allowing to export test results directly to [TestRail][1] instance via their [API][2].
4
4
 
@@ -6,177 +6,175 @@ require 'rubytree'
6
6
  require "testrail_rspec/version"
7
7
  require "testrail_rspec/client"
8
8
 
9
- module TestrailRspec
9
+ class TestrailRspec < RSpec::Core::Formatters::BaseTextFormatter
10
10
 
11
11
  RSpec.configuration.add_setting :testrail_formatter_options, :default => {}
12
12
 
13
- class Exporter < RSpec::Core::Formatters::BaseTextFormatter
14
- RSpec::Core::Formatters.register self, :start, :close, :dump_summary
15
- # # :example_started, :example_passed,
16
- # # :example_pending, :example_failed,
17
- # :dump_failures, :dump_pending
18
- # # :start_dump
13
+ RSpec::Core::Formatters.register self, :start, :close, :dump_summary
14
+ # # :example_started, :example_passed,
15
+ # # :example_pending, :example_failed,
16
+ # :dump_failures, :dump_pending
17
+ # # :start_dump
19
18
 
20
19
 
21
- # TODO: after exporter is done and working remove unnecessary overriden methods
20
+ # TODO: after exporter is done and working remove unnecessary overriden methods
22
21
 
23
- def initialize(output)
24
- @options = {}
25
- @project_id = nil
26
- super(output)
27
- end
22
+ def initialize(output)
23
+ @options = {}
24
+ @project_id = nil
25
+ super(output)
26
+ end
28
27
 
29
- # To start
30
- def start(notification)
31
- @options = RSpec.configuration.testrail_formatter_options
32
- @client = TestrailRspec::Client.new(@options)
33
- @client.get_projects.each { |project| @project_id = project['id'] if project['name'] == @options[:project] }
28
+ # To start
29
+ def start(notification)
30
+ @options = RSpec.configuration.testrail_formatter_options
31
+ @client = TestrailRspec::Client.new(@options)
32
+ @client.get_projects.each { |project| @project_id = project['id'] if project['name'] == @options[:project] }
34
33
 
35
- puts "TestRail Exporter [INFO] Executing #{notification.count} tests. Loaded in #{notification.load_time}"
34
+ puts "TestRail Exporter [INFO] Executing #{notification.count} tests. Loaded in #{notification.load_time}"
36
35
 
37
- super
38
- end
36
+ super
37
+ end
38
+
39
+ # Once per example group <-----------------------------------------------------------------------------
40
+ # def example_group_started(notification)
41
+ # groups = []
42
+ # current_group = notification.group
43
+ # until current_group.top_level?
44
+ # groups << current_group
45
+ # current_group = current_group.parent if current_group.parent_groups.size > 1
46
+ # end
47
+ #
48
+ # groups << current_group
49
+ #
50
+ # unless groups[0].examples.empty?
51
+ # groups.reverse.each_with_index do |group, idx|
52
+ # puts (idx == 0 ? "Spec: " : "") + (' ' *2 * idx) + "#{group.description}"
53
+ # end
54
+ # puts (' ' *2 * groups.size) + groups[0].examples.map(&:description).join("\n" + (' ' *2 * groups.size))
55
+ # end
56
+ #
57
+ # super
58
+ # end
59
+
60
+ # Once per example <-----------------------------------------------------------------------------------
61
+ # def example_started(notification)
62
+ # puts " - case: #{notification.example.description}"
63
+ # end
64
+
65
+ # One of these per example <---------------------------------------------------------------------------
66
+ # def example_passed(passed)
67
+ # puts "\tpass: #{passed.example.description}"
68
+ # end
69
+
70
+ # def example_failed(failure)
71
+ # puts "\tfail: #{failure.example.description}"
72
+ # end
73
+ #
74
+ # def example_pending(pending)
75
+ # puts "\tpend: #{pending.example.description}"
76
+ # end
77
+
78
+ # Optionally at any time <------------------------------------------------------------------------------
79
+ # def message(notification)
80
+ # puts "msg notification: #{notification.inspect}"
81
+ # super
82
+ # end
83
+
84
+ # At the end of the suite <-----------------------------------------------------------------------------
85
+ # def stop(notification)
86
+ # puts "stop notification: #{notification.inspect}"
87
+ # end
88
+
89
+ # def start_dump(null_notification)
90
+ # puts "start_dump notification: #{null_notification.inspect}"
91
+ # end
92
+ #
93
+ def dump_pending(notification)
94
+ # puts "dump pend notification: #{notification.inspect}"
95
+ # super
96
+ end
39
97
 
40
- # Once per example group <-----------------------------------------------------------------------------
41
- # def example_group_started(notification)
42
- # groups = []
43
- # current_group = notification.group
44
- # until current_group.top_level?
45
- # groups << current_group
46
- # current_group = current_group.parent if current_group.parent_groups.size > 1
47
- # end
48
- #
49
- # groups << current_group
50
- #
51
- # unless groups[0].examples.empty?
52
- # groups.reverse.each_with_index do |group, idx|
53
- # puts (idx == 0 ? "Spec: " : "") + (' ' *2 * idx) + "#{group.description}"
54
- # end
55
- # puts (' ' *2 * groups.size) + groups[0].examples.map(&:description).join("\n" + (' ' *2 * groups.size))
56
- # end
57
- #
58
- # super
59
- # end
60
-
61
- # Once per example <-----------------------------------------------------------------------------------
62
- # def example_started(notification)
63
- # puts " - case: #{notification.example.description}"
64
- # end
65
-
66
- # One of these per example <---------------------------------------------------------------------------
67
- # def example_passed(passed)
68
- # puts "\tpass: #{passed.example.description}"
69
- # end
70
-
71
- # def example_failed(failure)
72
- # puts "\tfail: #{failure.example.description}"
73
- # end
74
- #
75
- # def example_pending(pending)
76
- # puts "\tpend: #{pending.example.description}"
77
- # end
78
-
79
- # Optionally at any time <------------------------------------------------------------------------------
80
- # def message(notification)
81
- # puts "msg notification: #{notification.inspect}"
82
- # super
83
- # end
84
-
85
- # At the end of the suite <-----------------------------------------------------------------------------
86
- # def stop(notification)
87
- # puts "stop notification: #{notification.inspect}"
88
- # end
89
-
90
- # def start_dump(null_notification)
91
- # puts "start_dump notification: #{null_notification.inspect}"
92
- # end
93
- #
94
- def dump_pending(notification)
95
- # puts "dump pend notification: #{notification.inspect}"
96
- # super
98
+ def dump_failures(notification)
99
+ # puts "dump fail notification: #{notification.inspect}"
100
+ # super
101
+ end
102
+
103
+ def dump_summary(notification)
104
+ # Create project if it is not present / could do it setting controlled
105
+ if @project_id.nil?
106
+ puts "TestRail Exporter [INFO] Creating project: #{@options[:project]}"
107
+ @project_id = @client.add_project(@options[:project])['id']
97
108
  end
98
109
 
99
- def dump_failures(notification)
100
- # puts "dump fail notification: #{notification.inspect}"
101
- # super
110
+ suites = Hash.new do |h,k|
111
+ h[k] = Tree::TreeNode.new(k, @client.find_or_create_suite(k, @project_id) )
102
112
  end
103
113
 
104
- def dump_summary(notification)
105
- # Create project if it is not present / could do it setting controlled
106
- if @project_id.nil?
107
- puts "TestRail Exporter [INFO] Creating project: #{@options[:project]}"
108
- @project_id = @client.add_project(@options[:project])['id']
109
- end
110
114
 
111
- suites = Hash.new do |h,k|
112
- h[k] = Tree::TreeNode.new(k, @client.find_or_create_suite(k, @project_id) )
113
- end
115
+ notification.examples.each do |example|
116
+ build_hierarchy_tree!(suites, example)
117
+ end
114
118
 
119
+ suites.each { |_, suite| update_test_run(suite) }
115
120
 
116
- notification.examples.each do |example|
117
- build_hierarchy_tree!(suites, example)
118
- end
121
+ super
122
+ end
119
123
 
120
- suites.each { |_, suite| update_test_run(suite) }
124
+ def close(null_notification)
125
+ # TODO: could close any open connection
126
+ puts "TestRail Exporter [INFO] Closing..."
127
+ super
128
+ end
121
129
 
122
- super
123
- end
130
+ private
124
131
 
125
- def close(null_notification)
126
- # TODO: could close any open connection
127
- puts "TestRail Exporter [INFO] Closing..."
128
- super
129
- end
132
+ def get_path_for(node)
133
+ asc_arr = node.is_a?(RSpec::Core::Example) ? [node.description] : []
134
+ parent = (node.respond_to? :parent) ? node.parent : node.example_group
135
+ asc_arr << parent.description
136
+ asc_arr.push(*get_path_for(parent)) unless parent.top_level?
137
+ node.is_a?(RSpec::Core::Example) ? asc_arr.reverse : asc_arr
138
+ end
130
139
 
131
- private
140
+ def build_hierarchy_tree!(suites, example)
141
+ path = get_path_for(example)
132
142
 
133
- def get_path_for(node)
134
- asc_arr = node.is_a?(RSpec::Core::Example) ? [node.description] : []
135
- parent = (node.respond_to? :parent) ? node.parent : node.example_group
136
- asc_arr << parent.description
137
- asc_arr.push(*get_path_for(parent)) unless parent.top_level?
138
- node.is_a?(RSpec::Core::Example) ? asc_arr.reverse : asc_arr
139
- end
143
+ parent_node = suite_node = suites[path.shift]
144
+ path.unshift('Direct cases') unless path.size > 1
140
145
 
141
- def build_hierarchy_tree!(suites, example)
142
- path = get_path_for(example)
143
-
144
- parent_node = suite_node = suites[path.shift]
145
- path.unshift('Direct cases') unless path.size > 1
146
-
147
- path.each_with_index do |item, idx|
148
- child_node = (parent_node.children.map(&:name).include? item) ? parent_node[item] : nil
149
- if child_node and (idx + 1 == path.size)
150
- puts "TestRail Exporter [INFO] Second case with same path and name detected:\n\t#{suite_node.content['name']} -> #{path.join(' -> ')}"
151
- end
152
-
153
- unless child_node
154
- child_node = if idx + 1 == path.size
155
- Tree::TreeNode.new(item, { case: @client.find_or_create_case(item, parent_node.content, idx), result: example })
156
- else
157
- Tree::TreeNode.new(item, @client.find_or_create_section(item, suite_node.content, parent_node.content, idx))
158
- end
159
- parent_node << child_node
160
- end
161
- parent_node = child_node
146
+ path.each_with_index do |item, idx|
147
+ child_node = (parent_node.children.map(&:name).include? item) ? parent_node[item] : nil
148
+ if child_node and (idx + 1 == path.size)
149
+ puts "TestRail Exporter [INFO] Second case with same path and name detected:\n\t#{suite_node.content['name']} -> #{path.join(' -> ')}"
162
150
  end
163
151
 
164
- end
165
-
166
- def update_test_run(suite)
167
- run_id = @client.create_run(suite.content)['id']
168
- results = suite.each_leaf.map do |test|
169
- test_result = test.content[:result].execution_result
170
- run_time_seconds = test_result.run_time.round(0)
171
- {
172
- case_id: test.content[:case]['id'],
173
- status_id: TestrailRspec::STATUS[test_result.status],
174
- elapsed: (run_time_seconds == 0) ? nil : "#{run_time_seconds}s"
175
- }
152
+ unless child_node
153
+ child_node = if idx + 1 == path.size
154
+ Tree::TreeNode.new(item, { case: @client.find_or_create_case(item, parent_node.content, idx), result: example })
155
+ else
156
+ Tree::TreeNode.new(item, @client.find_or_create_section(item, suite_node.content, parent_node.content, idx))
157
+ end
158
+ parent_node << child_node
176
159
  end
177
- @client.add_results_for_cases(run_id, results)
160
+ parent_node = child_node
178
161
  end
179
162
 
163
+ end
180
164
 
165
+ def update_test_run(suite)
166
+ run_id = @client.create_run(suite.content)['id']
167
+ results = suite.each_leaf.map do |test|
168
+ test_result = test.content[:result].execution_result
169
+ run_time_seconds = test_result.run_time.round(0)
170
+ {
171
+ case_id: test.content[:case]['id'],
172
+ status_id: TestrailRspec::STATUS[test_result.status],
173
+ elapsed: (run_time_seconds == 0) ? nil : "#{run_time_seconds}s"
174
+ }
175
+ end
176
+ @client.add_results_for_cases(run_id, results)
181
177
  end
178
+
179
+
182
180
  end
@@ -1,3 +1,3 @@
1
1
  module TestrailRspec
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: testrail_rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Kubik