test_rail-api 0.4.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/LICENSE +22 -0
- data/lib/test_rail.rb +50 -0
- data/lib/test_rail/api.rb +355 -0
- data/lib/test_rail/case_type.rb +11 -0
- data/lib/test_rail/configuration.rb +10 -0
- data/lib/test_rail/initialize_with_api.rb +10 -0
- data/lib/test_rail/plan.rb +25 -0
- data/lib/test_rail/priority.rb +13 -0
- data/lib/test_rail/project.rb +42 -0
- data/lib/test_rail/result.rb +17 -0
- data/lib/test_rail/run.rb +31 -0
- data/lib/test_rail/section.rb +65 -0
- data/lib/test_rail/suite.rb +44 -0
- data/lib/test_rail/test.rb +18 -0
- data/lib/test_rail/test_case.rb +27 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 46276f27c1fc6c5bb81ad20d5b6f32fa83898dfb
|
4
|
+
data.tar.gz: 48849b393aadc4e1e2774bcef2b1f56b8455a81a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 869cf0734b672613ddbc0ae5d803cc8630a1971fff0c03c40a2256f3a531600f2e95f17f4905cb06f3cfb79fdc20366c90256bcddc2f437a39e1d86d26e6293c
|
7
|
+
data.tar.gz: 788cc15eeaf18360eb8a5e319065853a2ed85da6c5490402c3581195da109021e3dfc59dd7c4fc07dec459a181588ced7754dff522c6e32a66e7f2519d7a10ab
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 BBC
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/lib/test_rail.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
$: << File.dirname(__FILE__)
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
require 'json'
|
5
|
+
require "virtus"
|
6
|
+
require "test_rail/configuration"
|
7
|
+
require "test_rail/api"
|
8
|
+
require "test_rail/initialize_with_api"
|
9
|
+
require 'test_rail/project'
|
10
|
+
require 'test_rail/section'
|
11
|
+
require 'test_rail/suite'
|
12
|
+
require 'test_rail/test_case'
|
13
|
+
require 'test_rail/plan'
|
14
|
+
require 'test_rail/run'
|
15
|
+
require 'test_rail/test'
|
16
|
+
require 'test_rail/case_type'
|
17
|
+
require 'test_rail/priority'
|
18
|
+
|
19
|
+
module TestRail
|
20
|
+
|
21
|
+
NO_CONFIG_ERROR = <<eos
|
22
|
+
A configuration block must first be provided.
|
23
|
+
e.g:
|
24
|
+
TestRail.configure do |config|
|
25
|
+
config.user = "user"
|
26
|
+
config.password = "password"
|
27
|
+
config.namespace = "namespace"
|
28
|
+
end
|
29
|
+
eos
|
30
|
+
|
31
|
+
class << self
|
32
|
+
attr_accessor :configuration, :api
|
33
|
+
|
34
|
+
def configure
|
35
|
+
self.configuration = Configuration.new
|
36
|
+
yield(configuration)
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(method, *args, &block)
|
40
|
+
raise TestRail::NO_CONFIG_ERROR if configuration.nil?
|
41
|
+
api.send(method, *args, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def api
|
47
|
+
@api ||= TestRail::API.new(configuration.to_hash)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,355 @@
|
|
1
|
+
module TestRail
|
2
|
+
class API
|
3
|
+
attr_accessor :server
|
4
|
+
|
5
|
+
TESTRAIL = 'testrail.com'
|
6
|
+
HEADERS = { "Content-Type" => "application/json" }
|
7
|
+
|
8
|
+
STATUSES = {
|
9
|
+
:passed => 1,
|
10
|
+
:pass => 1,
|
11
|
+
:blocked => 2,
|
12
|
+
:untested => 3,
|
13
|
+
:retest => 4,
|
14
|
+
:failed => 5,
|
15
|
+
:fail => 5
|
16
|
+
}
|
17
|
+
|
18
|
+
|
19
|
+
# Initialize a new tesrail interface
|
20
|
+
# TestRail.new( :user => 'your@email.com',
|
21
|
+
# :password => 'passw0rd',
|
22
|
+
# :namespace => 'yourteam' )
|
23
|
+
def initialize(args)
|
24
|
+
raise "Need to provide arguments to constructor" if !args
|
25
|
+
@user = args[:user] or raise "Missing username (:user => 'email@address.com')"
|
26
|
+
@password = args[:password] or raise "Missing password (:password => 'abc123')"
|
27
|
+
@namespace = args[:namespace] or raise "Missing namespace (:namespace => 'testteam')"
|
28
|
+
|
29
|
+
@server = @namespace + "." + TESTRAIL
|
30
|
+
@host = URI('https://' + @server)
|
31
|
+
@api = "/index.php?/api/v2/"
|
32
|
+
@port = 443
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Project API calls
|
38
|
+
#
|
39
|
+
|
40
|
+
# Return a list of projects
|
41
|
+
def get_projects
|
42
|
+
list = get('get_projects')
|
43
|
+
list.collect do |item|
|
44
|
+
TestRail::Project.new(item.merge({ :api => self }))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return a specific project by id
|
49
|
+
# api.get_project( :id => 1 )
|
50
|
+
def get_project(args)
|
51
|
+
id = args[:id] or raise "Missing id (:id => 1)"
|
52
|
+
project = get('get_project', [id])
|
53
|
+
TestRail::Project.new(project.merge({ :api => self }))
|
54
|
+
end
|
55
|
+
|
56
|
+
# Search for a project by name
|
57
|
+
# testrail.find_project(:name => 'Amazing project')
|
58
|
+
def find_project(args)
|
59
|
+
name = args[:name] or raise "Missing name (:name => 'Amazing Project')"
|
60
|
+
projects = get_projects
|
61
|
+
projectexists = projects.select { |p| p.name == name }.first
|
62
|
+
if (!projectexists)
|
63
|
+
raise "Project Not Found."
|
64
|
+
end
|
65
|
+
return projectexists
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Suite API calls
|
70
|
+
#
|
71
|
+
|
72
|
+
# Add a new suite
|
73
|
+
# (If suite already exists, a new one is created with the same name)
|
74
|
+
# api.add_suite( :project_id => 1, :name => 'Cucumber features', :description => 'BDD Tests' )
|
75
|
+
# Returns the suite object
|
76
|
+
def add_suite(args)
|
77
|
+
project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
|
78
|
+
name = args[:name] or raise 'Missing name (:name => "Cucumber features")'
|
79
|
+
description = args[:description]
|
80
|
+
|
81
|
+
suite = post('add_suite', [project_id], { :name => name, :description => description })
|
82
|
+
TestRail::Suite.new(suite.merge({ :api => self }))
|
83
|
+
end
|
84
|
+
|
85
|
+
# Get a list of suites for a project
|
86
|
+
# api.get_suites( :project_id => 1 )
|
87
|
+
# Returns a list of suite objects
|
88
|
+
def get_suites(args)
|
89
|
+
id = args[:project_id] or raise "Missing project id (:project_id => 1)"
|
90
|
+
list = get('get_suites', [id])
|
91
|
+
list.collect do |item|
|
92
|
+
TestRail::Suite.new(item.merge({ :api => self }))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Get an existing suite by id
|
97
|
+
# testrail.get_suite( :id => 1 )
|
98
|
+
# Returns the suite object
|
99
|
+
def get_suite(args)
|
100
|
+
id = args[:id] or raise "Missing suite id (:id => 1)"
|
101
|
+
suite = get('get_suite', [id])
|
102
|
+
TestRail::Suite.new(suite.merge({ :api => self }))
|
103
|
+
end
|
104
|
+
|
105
|
+
def update_suite(args)
|
106
|
+
id = args[:id] or raise "Missing suite id (:id => 1)"
|
107
|
+
name = args[:name]
|
108
|
+
description = args[:description]
|
109
|
+
|
110
|
+
suite = post('update_suite', [id], { :name => name, :description => description })
|
111
|
+
TestRail::Suite.new(suite.merge({ :api => self }))
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# Section API Calls
|
116
|
+
#
|
117
|
+
def add_section(args)
|
118
|
+
project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
|
119
|
+
name = args[:name] or raise 'Missing name (:name => "UI features")'
|
120
|
+
suite_id = args[:suite_id] or raise 'Missing suite id (:suite_id => 1)'
|
121
|
+
parent_id = args[:parent_id]
|
122
|
+
|
123
|
+
section = post('add_section', [project_id], { :suite_id => suite_id, :name => name, :parent_id => parent_id })
|
124
|
+
TestRail::Section.new(section.merge({ :api => self, :project_id => project_id, :suite_id => suite_id }))
|
125
|
+
end
|
126
|
+
|
127
|
+
def get_sections(args)
|
128
|
+
project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
|
129
|
+
suite_id = args[:suite_id] or raise 'Missing suite id (:suite_id => 1)'
|
130
|
+
list = get('get_sections', [project_id], { :suite_id => suite_id })
|
131
|
+
list.collect do |item|
|
132
|
+
TestRail::Section.new(item.merge({ :api => self, :project_id => project_id }))
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def update_section(args)
|
137
|
+
section_id = args[:section_id] or raise 'Missing section id (:section_id => 1)'
|
138
|
+
project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
|
139
|
+
name = args[:name] or raise 'Missing name (:name => "UI features")'
|
140
|
+
suite_id = args[:suite_id] or raise 'Missing suite id (:suite_id => 1)'
|
141
|
+
parent_id = args[:parent_id]
|
142
|
+
|
143
|
+
section = post('update_section', [section_id], { :suite_id => suite_id, :name => name, :parent_id => parent_id })
|
144
|
+
TestRail::Section.new(section.merge({ :api => self, :project_id => project_id }))
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# Testcase API
|
149
|
+
#
|
150
|
+
def get_cases(args)
|
151
|
+
project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
|
152
|
+
suite_id = args[:suite_id] or raise 'Missing suite id (:suite_id => 1)'
|
153
|
+
section_id = args[:section_id]
|
154
|
+
list = get('get_cases', [project_id], { :suite_id => suite_id, :section_id => section_id })
|
155
|
+
list.collect do |item|
|
156
|
+
TestRail::TestCase.new(item.merge({ :api => self }))
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def get_case(args)
|
161
|
+
case_id = args[:case_id] or raise 'Missing test case id (:case_id => 1)'
|
162
|
+
testcase = get('get_case', [case_id])
|
163
|
+
TestRail::TestCase.new(testcase.merge({ :api => self }))
|
164
|
+
end
|
165
|
+
|
166
|
+
def add_case(args)
|
167
|
+
section_id = args[:section_id] or raise 'Missing section id (:section_id => 1)'
|
168
|
+
title = args[:title] or raise 'Missing title (:title => "Use logs in")'
|
169
|
+
steps = args[:steps]
|
170
|
+
type_id = args[:type_id]
|
171
|
+
priority_id = args[:priority_id]
|
172
|
+
|
173
|
+
test_case = post('add_case', [section_id],
|
174
|
+
{ :title => title, :custom_steps => steps,
|
175
|
+
:type_id => type_id, :priority_id => priority_id })
|
176
|
+
|
177
|
+
TestRail::TestCase.new(test_case.merge({ :api => self }))
|
178
|
+
end
|
179
|
+
|
180
|
+
def update_case(args)
|
181
|
+
case_id = args[:case_id] or raise "Missing case id (:case_id => 1)"
|
182
|
+
|
183
|
+
new_values = {}
|
184
|
+
|
185
|
+
new_values[:title] = args[:title] if args[:title]
|
186
|
+
new_values[:custom_steps] = args[:steps] if args[:steps]
|
187
|
+
new_values[:priority_id] = args[:priority_id] if args[:priority_id]
|
188
|
+
new_values[:type_id] = args[:type_id] if args[:type_id]
|
189
|
+
|
190
|
+
test_case = post('update_case', [case_id], new_values )
|
191
|
+
|
192
|
+
TestRail::TestCase.new(test_case.merge({ :api => self }))
|
193
|
+
end
|
194
|
+
|
195
|
+
#
|
196
|
+
# Results API
|
197
|
+
#
|
198
|
+
def add_result_for_case(args)
|
199
|
+
run_id = args[:run_id] or raise "Missing test run id (:run_id => 1)"
|
200
|
+
case_id = args[:case_id] or raise "Missing test case id (:case_id => 1)"
|
201
|
+
|
202
|
+
status_id = args[:status_id]
|
203
|
+
if !status_id
|
204
|
+
status_id = STATUSES[args[:status].to_sym]
|
205
|
+
raise "Couldn't determine result status '#{args[:status]}'" if !status_id
|
206
|
+
end
|
207
|
+
|
208
|
+
result = {
|
209
|
+
:status_id => status_id,
|
210
|
+
:comment => args[:comment],
|
211
|
+
:version => args[:version],
|
212
|
+
:elapsed => args[:elapsed]
|
213
|
+
}
|
214
|
+
|
215
|
+
test_rail_result = post('add_result_for_case', [run_id, case_id], result)
|
216
|
+
#TODO new this into a relevant TestRails object
|
217
|
+
end
|
218
|
+
|
219
|
+
# Given a run id, retrieve a plan
|
220
|
+
def get_run(args)
|
221
|
+
run_id = args[:run_id] or raise "Missing run id ( :run_id => 1)"
|
222
|
+
|
223
|
+
result = get('get_run', [run_id])
|
224
|
+
TestRail::Run.new(result.merge({ :api => self }))
|
225
|
+
end
|
226
|
+
|
227
|
+
# Creates a new run
|
228
|
+
# api.add_run( :project_id => project_id, :suite_id => suite_id )
|
229
|
+
# Optional parameters:
|
230
|
+
# name: Name to give the run
|
231
|
+
# description: Description of the run
|
232
|
+
def add_run(args)
|
233
|
+
project_id = args[:project_id] or raise "Missing project id ( :project_id => 1)"
|
234
|
+
suite_id = args[:suite_id] or raise "Missing suite id ( :suite_id => 1)"
|
235
|
+
|
236
|
+
params = {
|
237
|
+
:suite_id => suite_id,
|
238
|
+
:name => args[:name],
|
239
|
+
:description => args[:description]
|
240
|
+
}
|
241
|
+
|
242
|
+
result = post('add_run', [project_id], params)
|
243
|
+
TestRail::Run.new(result.merge({ :api => self }))
|
244
|
+
end
|
245
|
+
|
246
|
+
# Given a plan id, returns a plan (and populates internal run objects)
|
247
|
+
def get_plan(args)
|
248
|
+
plan_id = args[:plan_id] or raise "Missing plan id (:plan_id => 1)"
|
249
|
+
|
250
|
+
result = get('get_plan', [plan_id])
|
251
|
+
|
252
|
+
raw_runs = result['entries'].collect { |e| e['runs'] }.flatten
|
253
|
+
runs = raw_runs.each.collect { |r| TestRail::Run.new(r.merge({ :api => self })) }
|
254
|
+
|
255
|
+
plan = TestRail::Plan.new(result.merge({ :api => self, :runs => runs }))
|
256
|
+
|
257
|
+
plan
|
258
|
+
end
|
259
|
+
|
260
|
+
def get_tests(args)
|
261
|
+
run_id = args[:run_id] or raise "Missing run id (:run_id => 1)"
|
262
|
+
list = get('get_tests', [run_id])
|
263
|
+
|
264
|
+
list.collect do |item|
|
265
|
+
TestRail::Test.new(item.merge({ :api => self }))
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Get all the case types defined for this testrail instance
|
270
|
+
def get_case_types
|
271
|
+
result = get('get_case_types')
|
272
|
+
|
273
|
+
result.collect do |type|
|
274
|
+
TestRail::CaseType.new(type.merge({ :api => self }))
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
# Get all the priorities defined for this testrail instance
|
279
|
+
def get_priorities
|
280
|
+
result = get('get_priorities')
|
281
|
+
|
282
|
+
result.collect do |priority|
|
283
|
+
TestRail::Priority.new(priority.merge({ :api => self }))
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
#
|
289
|
+
# Private methods
|
290
|
+
#
|
291
|
+
private
|
292
|
+
|
293
|
+
# Creates and caches an http object that is used by the get and
|
294
|
+
# post commands
|
295
|
+
def http
|
296
|
+
if !@http
|
297
|
+
path = @host.to_s + @api
|
298
|
+
uri = URI.parse(path)
|
299
|
+
|
300
|
+
proxy_env = ENV['HTTP_PROXY']
|
301
|
+
|
302
|
+
if proxy_env
|
303
|
+
proxy_uri = URI(proxy_env)
|
304
|
+
proxy = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port)
|
305
|
+
@http = proxy.new(uri.host, uri.port)
|
306
|
+
else
|
307
|
+
@http = Net::HTTP.new(uri.host, uri.port)
|
308
|
+
end
|
309
|
+
@http.use_ssl = true
|
310
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
311
|
+
end
|
312
|
+
|
313
|
+
@http
|
314
|
+
end
|
315
|
+
|
316
|
+
def get(call, array_args=[], hash_args={})
|
317
|
+
send_request('get', call, array_args, hash_args, nil)
|
318
|
+
end
|
319
|
+
|
320
|
+
def post(call, array_args=[], post_args={})
|
321
|
+
send_request('post', call, array_args, nil, post_args)
|
322
|
+
end
|
323
|
+
|
324
|
+
# get request
|
325
|
+
def send_request(protocol, call, array_args = [], hash_args = {}, post_data = {})
|
326
|
+
path = @host.to_s + @api + call
|
327
|
+
if array_args
|
328
|
+
path += '/' + array_args.join('/')
|
329
|
+
end
|
330
|
+
if hash_args
|
331
|
+
path += '&' + hash_args.map { |k, v| "#{k.to_s}=#{v}" }.join('&')
|
332
|
+
end
|
333
|
+
uri = URI.parse(path)
|
334
|
+
|
335
|
+
request = nil
|
336
|
+
if protocol == 'get'
|
337
|
+
request = Net::HTTP::Get.new(uri.request_uri, HEADERS)
|
338
|
+
else
|
339
|
+
request = Net::HTTP::Post.new(uri.request_uri, HEADERS)
|
340
|
+
request.body = post_data.to_json
|
341
|
+
end
|
342
|
+
request.basic_auth(@user, @password)
|
343
|
+
|
344
|
+
response = http.request(request)
|
345
|
+
|
346
|
+
body = JSON.parse(response.body)
|
347
|
+
|
348
|
+
if response.code && response.code.to_i == 200
|
349
|
+
return body
|
350
|
+
else
|
351
|
+
raise body["error"].to_s
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module TestRail
|
2
|
+
class Plan
|
3
|
+
include Virtus.model
|
4
|
+
|
5
|
+
attribute :id
|
6
|
+
attribute :name
|
7
|
+
attribute :description
|
8
|
+
attribute :milestone_id
|
9
|
+
attribute :assignedto_id
|
10
|
+
attribute :is_completed
|
11
|
+
attribute :completed_on
|
12
|
+
attribute :project_id
|
13
|
+
attribute :created_on
|
14
|
+
attribute :created_by
|
15
|
+
attribute :url
|
16
|
+
attribute :entries
|
17
|
+
attribute :runs, Array
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def find_by_id(plan_id)
|
21
|
+
TestRail.get_plan(plan_id: plan_id)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module TestRail
|
2
|
+
class Project
|
3
|
+
include Virtus.model
|
4
|
+
include InitializeWithApi
|
5
|
+
|
6
|
+
attribute :id
|
7
|
+
attribute :name
|
8
|
+
attribute :announcement
|
9
|
+
attribute :show_announcement
|
10
|
+
attribute :is_completed
|
11
|
+
attribute :completed_on
|
12
|
+
attribute :url
|
13
|
+
|
14
|
+
# Return a list of suites belonging to this project
|
15
|
+
def suites
|
16
|
+
@api.get_suites( :project_id => @id )
|
17
|
+
end
|
18
|
+
|
19
|
+
# Create a new suite for this project
|
20
|
+
def new_suite( args )
|
21
|
+
@api.add_suite( args.merge({:project_id => id}) )
|
22
|
+
end
|
23
|
+
|
24
|
+
# Find a suite in this project based on the suite name
|
25
|
+
# project.find_suite( :name => "My Suite" )
|
26
|
+
def find_suite( args )
|
27
|
+
name = args[:name] or raise "Need to provide the name of a suite"
|
28
|
+
suites.select{ |s| s.name == name }.first
|
29
|
+
end
|
30
|
+
|
31
|
+
# Find or create a suite in this project based on the suite name
|
32
|
+
# project.find_or_create_suite( :name => "My Suite" )
|
33
|
+
def find_or_create_suite( args )
|
34
|
+
name = args[:name] or raise "Need to provide the name of a suite"
|
35
|
+
suite = self.find_suite( args )
|
36
|
+
if suite.nil?
|
37
|
+
suite = new_suite( args )
|
38
|
+
end
|
39
|
+
suite
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module TestRail
|
2
|
+
class Result
|
3
|
+
include Virtus.model
|
4
|
+
|
5
|
+
attribute :id
|
6
|
+
attribute :test_id
|
7
|
+
attribute :status_id
|
8
|
+
attribute :comment
|
9
|
+
attribute :version
|
10
|
+
attribute :elapsed
|
11
|
+
attribute :created_by
|
12
|
+
attribute :created_on
|
13
|
+
attribute :assignedto_id
|
14
|
+
attribute :defects
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module TestRail
|
2
|
+
class Run
|
3
|
+
include Virtus.model
|
4
|
+
include InitializeWithApi
|
5
|
+
|
6
|
+
attribute :id
|
7
|
+
attribute :suite_id
|
8
|
+
attribute :name
|
9
|
+
attribute :description
|
10
|
+
attribute :milestone_id
|
11
|
+
attribute :assignedto_id
|
12
|
+
attribute :include_all
|
13
|
+
attribute :is_completed
|
14
|
+
attribute :completed_on
|
15
|
+
attribute :config
|
16
|
+
attribute :url
|
17
|
+
attribute :passed_count
|
18
|
+
attribute :blocked_count
|
19
|
+
attribute :untested_count
|
20
|
+
attribute :retest_count
|
21
|
+
attribute :failed_count
|
22
|
+
|
23
|
+
def tests
|
24
|
+
@api.get_tests(:run_id => id)
|
25
|
+
end
|
26
|
+
|
27
|
+
def suite
|
28
|
+
@api.get_suite(:id => suite_id)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module TestRail
|
2
|
+
class Section
|
3
|
+
include Virtus.model
|
4
|
+
include InitializeWithApi
|
5
|
+
|
6
|
+
attribute :id
|
7
|
+
attribute :name
|
8
|
+
attribute :project_id
|
9
|
+
attribute :parent_id
|
10
|
+
attribute :url
|
11
|
+
attribute :suite_id
|
12
|
+
|
13
|
+
def update
|
14
|
+
@api.update_section( :section_id => @id, :name => name, :project_id => @project_id, :suite_id => @suite_id, :parent_id => @id)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Get a list of sub-sections
|
18
|
+
def sub_sections
|
19
|
+
sections = @api.get_sections( :project_id => @project_id, :suite_id => @suite_id )
|
20
|
+
sections.reject{ |s| s.parent_id != @id }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Get a list of test-cases
|
24
|
+
def test_cases
|
25
|
+
@api.get_cases( :project_id => @project_id, :suite_id => @suite_id, :section_id => @id )
|
26
|
+
end
|
27
|
+
|
28
|
+
def new_test_case(args)
|
29
|
+
@api.add_case(args.merge({:section_id => @id }))
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_test_case( args )
|
33
|
+
title = args[:title] or raise "Need to provide the title of a test case"
|
34
|
+
test_cases.select{ |c| c.title == title }.first
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_or_create_test_case( args )
|
38
|
+
title = args[:title] or raise "Need to provide the title of a test case"
|
39
|
+
test_case = self.find_test_case( args )
|
40
|
+
if test_case.nil?
|
41
|
+
test_case = new_test_case( args )
|
42
|
+
end
|
43
|
+
test_case
|
44
|
+
end
|
45
|
+
|
46
|
+
# suite.add_section( :name => 'Section name )
|
47
|
+
def add_section( args )
|
48
|
+
@api.add_section( :project_id => project_id, :parent_id => @id, :suite_id => @suite_id, :name => args[:name] )
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_section( args )
|
52
|
+
name = args[:name] or raise "Need to provide the sub-section name (:name => 'subsection01')"
|
53
|
+
sub_sections.select{ |s| s.name == name }.first
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_or_create_section( args )
|
57
|
+
name = args[:name] or raise "Need to provide the sub-section name (:name => 'subsection01')"
|
58
|
+
section = self.find_section( args )
|
59
|
+
if section.nil?
|
60
|
+
section = add_section( args )
|
61
|
+
end
|
62
|
+
section
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module TestRail
|
2
|
+
class Suite
|
3
|
+
include Virtus.model
|
4
|
+
include InitializeWithApi
|
5
|
+
|
6
|
+
attribute :id
|
7
|
+
attribute :name
|
8
|
+
attribute :description
|
9
|
+
attribute :project_id
|
10
|
+
attribute :url
|
11
|
+
|
12
|
+
# Save changes made to this object back in testrail
|
13
|
+
# suite.description = "New description"
|
14
|
+
# suite.update
|
15
|
+
def update
|
16
|
+
@api.update_suite( :id => @id, :name => @name, :description => @description)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get a list of sections for this suite
|
20
|
+
def sections
|
21
|
+
sections = @api.get_sections( :project_id => @project_id, :suite_id => @id )
|
22
|
+
sections.reject{ |s| s.parent_id != nil }
|
23
|
+
end
|
24
|
+
|
25
|
+
# suite.add_section( :name => 'Section name )
|
26
|
+
def add_section( args)
|
27
|
+
@api.add_section( :project_id => project_id, :suite_id => @id, :name => args[:name] )
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_section( args )
|
31
|
+
name = args[:name] or raise "Need to provide the section name"
|
32
|
+
sections.select{ |s| s.name == name }.first
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_or_create_section( args )
|
36
|
+
name = args[:name] or raise "Need to provide the section name"
|
37
|
+
section = self.find_section( args )
|
38
|
+
if section.nil?
|
39
|
+
section = add_section( args )
|
40
|
+
end
|
41
|
+
section
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module TestRail
|
2
|
+
class Test
|
3
|
+
include Virtus.model
|
4
|
+
|
5
|
+
attribute :id
|
6
|
+
attribute :case_id
|
7
|
+
attribute :status_id
|
8
|
+
attribute :assignedto_id
|
9
|
+
attribute :run_id
|
10
|
+
attribute :title
|
11
|
+
attribute :type_id
|
12
|
+
attribute :priority_id
|
13
|
+
attribute :estimate
|
14
|
+
attribute :estimate_forcast
|
15
|
+
attribute :custom_steps
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module TestRail
|
2
|
+
class TestCase
|
3
|
+
include Virtus.model
|
4
|
+
include InitializeWithApi
|
5
|
+
|
6
|
+
attribute :id
|
7
|
+
attribute :title
|
8
|
+
attribute :type_id
|
9
|
+
attribute :priority_id
|
10
|
+
attribute :estimate
|
11
|
+
attribute :milestone_id
|
12
|
+
attribute :refs
|
13
|
+
attribute :url
|
14
|
+
|
15
|
+
# Save changes made to this object back in testrail
|
16
|
+
def update
|
17
|
+
@api.update_case( :case_id => @id, :title => @title )
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_result( args )
|
21
|
+
run_id = args[:run_id] or raise "Need to provide a run ID to store result against"
|
22
|
+
status = args[:status] or raise "Need to provide a result status (e.g. :status => :passed)"
|
23
|
+
version = args[:version]
|
24
|
+
@api.add_result_for_case( :case_id => id, :run_id => run_id, :status => status, :version => version )
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: test_rail-api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- BBC
|
8
|
+
- David Buckhurst
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-05-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: virtus
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '2.14'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2.14'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: faker
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.0'
|
70
|
+
description: Ruby Client for v2 TestRail API
|
71
|
+
email: david.buckhurst@bbc.co.uk
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- LICENSE
|
77
|
+
- lib/test_rail.rb
|
78
|
+
- lib/test_rail/api.rb
|
79
|
+
- lib/test_rail/case_type.rb
|
80
|
+
- lib/test_rail/configuration.rb
|
81
|
+
- lib/test_rail/initialize_with_api.rb
|
82
|
+
- lib/test_rail/plan.rb
|
83
|
+
- lib/test_rail/priority.rb
|
84
|
+
- lib/test_rail/project.rb
|
85
|
+
- lib/test_rail/result.rb
|
86
|
+
- lib/test_rail/run.rb
|
87
|
+
- lib/test_rail/section.rb
|
88
|
+
- lib/test_rail/suite.rb
|
89
|
+
- lib/test_rail/test.rb
|
90
|
+
- lib/test_rail/test_case.rb
|
91
|
+
homepage: https://github.com/bbc/test_rail-api
|
92
|
+
licenses:
|
93
|
+
- MIT
|
94
|
+
metadata: {}
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.4.8
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Test Rail API
|
115
|
+
test_files: []
|
116
|
+
has_rdoc:
|