testrail_rspec 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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