test_linker 0.1.1 → 1.0.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.
- data/.infinity_test +7 -0
- data/.rspec +1 -1
- data/ChangeLog.rdoc +26 -0
- data/Gemfile +4 -6
- data/README.rdoc +35 -34
- data/Rakefile +39 -36
- data/features/step_definitions/get_info_steps.rb +12 -12
- data/features/support/env.rb +8 -4
- data/lib/core_ext/hash_patch.rb +24 -0
- data/lib/core_ext/xmlrpc_client_patch.rb +7 -0
- data/lib/test_linker.rb +42 -9
- data/lib/test_linker/helpers.rb +68 -81
- data/lib/test_linker/version.rb +1 -1
- data/lib/test_linker/wrapper.rb +147 -158
- data/spec/core_ext/xmlrpc_client_patch_spec.rb +16 -0
- data/spec/spec_helper.rb +23 -5
- data/spec/test_linker/wrapper_spec.rb +168 -0
- data/spec/test_linker_spec.rb +26 -0
- data/test_linker.gemspec +32 -43
- metadata +148 -119
- data/gemspec.yml +0 -25
data/.infinity_test
ADDED
data/.rspec
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--colour --format documentation
|
1
|
+
--colour --format documentation --tty
|
data/ChangeLog.rdoc
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
=== 1.0.0 / 2011-05-08
|
2
|
+
|
3
|
+
* Added support for new (old) Rubies:
|
4
|
+
* 1.8.7
|
5
|
+
* jruby 1.6.1
|
6
|
+
* ree 1.8.7
|
7
|
+
* Hash keys are all now symbols.
|
8
|
+
* Renamed methods:
|
9
|
+
* Wrapper#project_test_plans to Wrapper#test_plans.
|
10
|
+
* Wrapper#create_test_project to Wrapper#create_project.
|
11
|
+
* Wrapper#upload_test_project_attachment to Wrapper#upload_project_attachment.
|
12
|
+
* Wrapper#first_level_test_suites_for_test_project to Wrapper#first_level_test_suites_for_project.
|
13
|
+
* Helpers#test_project_id to Helpers#project_id.
|
14
|
+
* Helpers#test_project_by_name to Helpers#project_by_name.
|
15
|
+
* New Helper method:
|
16
|
+
* #find_projects
|
17
|
+
* Helper#find_projects and Helper#find_test_plans take a trailing parameter that
|
18
|
+
let's you specify which attribute to match on--that defaults to :name.
|
19
|
+
* Added ability to log XMLRPC calls that go through Net::HTTP.
|
20
|
+
* Development stuff:
|
21
|
+
* Stopped using ore for gem bundling; just use Jeweler now.
|
22
|
+
|
23
|
+
=== 0.1.1 / 2011-03-24
|
24
|
+
|
25
|
+
* Fixed dumb dependency on self to install.
|
26
|
+
|
1
27
|
=== 0.1.0 / 2011-03-24
|
2
28
|
|
3
29
|
* Initial release:
|
data/Gemfile
CHANGED
@@ -4,13 +4,11 @@ source :rubygems
|
|
4
4
|
gem 'versionomy', '~> 0.4.0'
|
5
5
|
|
6
6
|
group :development do
|
7
|
+
gem 'bundler', '~> 1.0.0'
|
7
8
|
gem 'cucumber', '~> 0.10.0'
|
8
|
-
gem '
|
9
|
-
gem '
|
10
|
-
gem 'ore-core', '~> 0.1.4'
|
11
|
-
gem 'ore-tasks', '~> 0.5.0'
|
9
|
+
gem 'fakeweb', '~> 1.3.0'
|
10
|
+
gem 'jeweler', '~> 1.6.0'
|
12
11
|
gem 'rspec', '~> 2.5'
|
13
|
-
gem 'simplecov', '>= 0.4.0', :require => false
|
14
|
-
gem 'jeweler', '~> 1.5.0'
|
12
|
+
gem 'simplecov', '>= 0.4.0', :require => false if RUBY_VERSION >= "1.9"
|
15
13
|
gem 'yard', '~> 0.6.0'
|
16
14
|
end
|
data/README.rdoc
CHANGED
@@ -15,32 +15,37 @@ easier. This supports TestLink APIs 1.0 Beta 5 (from TestLink 1.8.x) and 1.0
|
|
15
15
|
== Features
|
16
16
|
|
17
17
|
* Basic wrapper around existing XMLRPC functions.
|
18
|
-
* Allow for calling methods via Ruby style (#projects) or XMLRPC style (#getProjects)
|
19
|
-
* Support for TestLink API versions 1.0 Beta 5 and 1.0
|
20
|
-
* Only one error/exception type: TestLinker::Error
|
21
|
-
* Limited set of helper methods, attempting to fill in gaps from the API
|
18
|
+
* Allow for calling methods via Ruby style (#projects) or XMLRPC style (#getProjects).
|
19
|
+
* Support for TestLink API versions 1.0 Beta 5 and 1.0.
|
20
|
+
* Only one error/exception type: TestLinker::Error.
|
21
|
+
* Limited set of helper methods, attempting to fill in gaps from the API.
|
22
22
|
|
23
23
|
== Examples
|
24
24
|
|
25
|
+
Get results to a CSV file:
|
26
|
+
|
25
27
|
require 'test_linker'
|
28
|
+
require 'pp'
|
26
29
|
|
27
|
-
server = 'http://testlink
|
30
|
+
server = 'http://testlink'
|
28
31
|
dev_key = "90b7941411928ae0a84d19f365a01a63"
|
29
|
-
tl_project = "
|
32
|
+
tl_project = "My nifty project"
|
33
|
+
tl = TestLinker.new(server, dev_key)
|
30
34
|
|
31
|
-
|
35
|
+
# Write out the CSV headers
|
36
|
+
csv_file_name = "report.csv"
|
32
37
|
csv_file = File.new(csv_file_name, "w")
|
33
|
-
csv_file.write "Build,Passed,Failed,Blocked,
|
34
|
-
|
35
|
-
tl = TestLinker.new(server, dev_key)
|
38
|
+
csv_file.write "Build,Passed,Failed,Blocked,TOTAL,Overall %,Overall % (+B)\n"
|
36
39
|
|
37
|
-
|
38
|
-
|
40
|
+
# Get the list of test plans that I want to report on
|
41
|
+
project_id = tl.project_id tl_project
|
42
|
+
test_plans = tl.find_test_plans(project_id, /^Component.+1.0/)
|
39
43
|
puts "All test plans for project #{project_id}"
|
40
|
-
|
44
|
+
pp test_plans
|
41
45
|
|
46
|
+
# Get a list of all builds from those test plans
|
42
47
|
builds = test_plans.collect do |test_plan|
|
43
|
-
tl.builds_for_test_plan(test_plan[
|
48
|
+
tl.builds_for_test_plan(test_plan[:id])
|
44
49
|
end
|
45
50
|
builds.flatten!
|
46
51
|
|
@@ -48,66 +53,62 @@ easier. This supports TestLink APIs 1.0 Beta 5 (from TestLink 1.8.x) and 1.0
|
|
48
53
|
overall[:pass] = 0
|
49
54
|
overall[:failed] = 0
|
50
55
|
overall[:blocked] = 0
|
51
|
-
overall[:pass_rates] =
|
52
56
|
results = {}
|
53
57
|
|
58
|
+
# Total up results for each build and write to the CSV file
|
54
59
|
builds.each do |build|
|
55
60
|
results[:pass] = 0
|
56
61
|
results[:failed] = 0
|
57
62
|
results[:blocked] = 0
|
58
|
-
results[:skipped] = 0
|
59
63
|
|
60
|
-
test_cases = tl.test_cases_for_test_plan(build[
|
61
|
-
{
|
64
|
+
test_cases = tl.test_cases_for_test_plan(build[:testplan_id],
|
65
|
+
{ :buildid => build[:id] })
|
62
66
|
|
63
67
|
test_cases.each_value do |test_case|
|
64
|
-
case test_case[
|
68
|
+
case test_case[:exec_status]
|
65
69
|
when "p"
|
66
70
|
results[:pass] += 1
|
67
71
|
when "f"
|
68
72
|
results[:failed] += 1
|
69
73
|
when "b"
|
70
74
|
results[:blocked] += 1
|
71
|
-
when "s"
|
72
|
-
results[:skipped] += 1
|
73
75
|
end
|
74
76
|
end
|
75
77
|
|
76
78
|
overall[:pass] += results[:pass]
|
77
79
|
overall[:failed] += results[:failed]
|
78
80
|
overall[:blocked] += results[:blocked]
|
79
|
-
build_total = results[:pass] + results[:failed] + results[:blocked]
|
80
|
-
|
81
|
+
build_total = results[:pass] + results[:failed] + results[:blocked]
|
82
|
+
|
81
83
|
overall_rate = "%2.2f" % (overall[:pass] * 100 / (overall[:pass] +
|
82
84
|
overall[:failed]).to_f)
|
83
|
-
overall[:pass_rates] << overall_rate.to_f
|
84
85
|
overall_rate_plus_blocked = "%2.2f" % (overall[:pass] * 100 / (overall[:pass] +
|
85
86
|
overall[:failed] + overall[:blocked]).to_f)
|
86
87
|
|
87
|
-
|
88
|
-
|
89
|
-
[results[:pass], results[:failed], results[:blocked], results[:skipped],
|
90
|
-
build_total, overall_rate, overall_rate_plus_blocked]
|
91
|
-
]
|
92
|
-
|
93
|
-
csv_line = "#{build["name"]},#{results[:pass]},#{results[:failed]},#{results[:blocked]},"
|
94
|
-
csv_line << "#{results[:skipped]},#{build_total},#{overall_rate},#{overall_rate_plus_blocked}\n"
|
88
|
+
csv_line = "#{build[:name]},#{results[:pass]},#{results[:failed]},#{results[:blocked]},"
|
89
|
+
csv_line << "#{build_total},#{overall_rate},#{overall_rate_plus_blocked}\n"
|
95
90
|
csv_file.write csv_line
|
96
91
|
end
|
92
|
+
|
93
|
+
csv_file.close
|
94
|
+
|
97
95
|
|
98
96
|
== Requirements
|
99
97
|
|
100
98
|
* Rubies (tested)
|
99
|
+
* 1.8.7
|
101
100
|
* 1.9.2
|
101
|
+
* jruby 1.6.1
|
102
|
+
* ree 1.8.7
|
102
103
|
* Gems
|
103
104
|
* versionomy, ~> 0.4.0
|
104
105
|
* Gems (development)
|
105
106
|
* bundler, ~> 1.0.0
|
106
107
|
* cucumber, ~> 0.10.0
|
108
|
+
* fakeweb, ~> 1.3.0
|
107
109
|
* jeweler, ~> 1.5.0
|
108
|
-
* ore, ~> 0.7.2
|
109
|
-
* ore-core, ~> 0.1.4
|
110
110
|
* rspec, ~> 2.5.0
|
111
|
+
* simplecov, >= 0.4.0
|
111
112
|
* yard, ~> 0.6.0
|
112
113
|
|
113
114
|
Getting it all running (on the TestLink side):
|
data/Rakefile
CHANGED
@@ -1,48 +1,51 @@
|
|
1
|
-
require '
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
2
3
|
|
3
4
|
begin
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
rescue LoadError => e
|
9
|
-
STDERR.puts e.message
|
10
|
-
STDERR.puts "Run `gem install ore-tasks` to install 'ore/tasks'."
|
11
|
-
end
|
12
|
-
begin
|
13
|
-
require 'bundler'
|
14
|
-
rescue LoadError => e
|
15
|
-
STDERR.puts e.message
|
16
|
-
STDERR.puts "Run `gem install bundler` to install Bundler."
|
5
|
+
Bundler.setup(:default, :development)
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.puts e.message
|
8
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
17
9
|
exit e.status_code
|
18
10
|
end
|
19
11
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
$:.unshift Dir.pwd + "/lib"
|
15
|
+
require 'test_linker'
|
16
|
+
require 'jeweler'
|
17
|
+
Jeweler::Tasks.new do |gem|
|
18
|
+
gem.name = "test_linker"
|
19
|
+
gem.version = TestLinker::VERSION
|
20
|
+
gem.homepage = "http://github.com/turboladen/test_linker"
|
21
|
+
gem.license = "MIT"
|
22
|
+
gem.summary = %Q{An interface to the TestLink XMLRPC API}
|
23
|
+
gem.description = %Q{This is a Ruby wrapper around the TestLink XMLRPC API, thus allowing access to
|
24
|
+
your TestLink test projects, plans, cases, and results using Ruby. We've added
|
25
|
+
a few helper methods as well to allow for getting at more of your data a little
|
26
|
+
easier. This supports TestLink APIs 1.0 Beta 5 (from TestLink 1.8.x) and 1.0
|
27
|
+
(from TestLink 1.9.x)..}
|
28
|
+
gem.email = "steve.loveless@gmail.com"
|
29
|
+
gem.authors = ["turboladen"]
|
30
|
+
gem.add_bundler_dependencies
|
26
31
|
end
|
32
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
33
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
RSpec::Core::RakeTask.new
|
33
|
-
task :test => :spec
|
34
|
-
task :default => :spec
|
35
|
-
rescue LoadError => e
|
36
|
-
task :spec do
|
37
|
-
abort "Please run `gem install rspec` to install RSpec."
|
38
|
-
end
|
34
|
+
require 'rspec/core'
|
35
|
+
require 'rspec/core/rake_task'
|
36
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
37
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
39
38
|
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
41
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
42
|
+
spec.rcov = true
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'cucumber/rake/task'
|
46
|
+
Cucumber::Rake::Task.new(:features)
|
47
|
+
|
48
|
+
task :default => :spec
|
44
49
|
|
45
50
|
require 'yard'
|
46
51
|
YARD::Rake::YardocTask.new
|
47
|
-
task :doc => :yard
|
48
|
-
|
@@ -1,10 +1,10 @@
|
|
1
1
|
Given /^I know the name of a project$/ do
|
2
|
-
@test_project_name = @server.projects.last[
|
2
|
+
@test_project_name = @server.projects.last[:name]
|
3
3
|
@test_project_name.should_not be_nil
|
4
4
|
end
|
5
5
|
|
6
6
|
Given /^I know the name of a test plan in that project$/ do
|
7
|
-
@original_test_plan_name = @test_plans.last[
|
7
|
+
@original_test_plan_name = @test_plans.last[:name]
|
8
8
|
@original_test_plan_name.should_not be_nil
|
9
9
|
end
|
10
10
|
|
@@ -15,7 +15,7 @@ end
|
|
15
15
|
|
16
16
|
Given /^I have a list of test plans$/ do
|
17
17
|
#When "I ask for the list of test plans"
|
18
|
-
@test_plans = @server.
|
18
|
+
@test_plans = @server.test_plans(@project_list.last[:id])
|
19
19
|
end
|
20
20
|
|
21
21
|
When /^I ask for the list of projects$/ do
|
@@ -23,16 +23,16 @@ When /^I ask for the list of projects$/ do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
When /^I ask for the list of test plans$/ do
|
26
|
-
@test_plans = @server.
|
26
|
+
@test_plans = @server.test_plans(@project_list.last[:id])
|
27
27
|
end
|
28
28
|
|
29
29
|
When /^I ask for that project by name$/ do
|
30
|
-
@requested_test_project_name = @server.
|
30
|
+
@requested_test_project_name = @server.project_by_name(@test_project_name)
|
31
31
|
end
|
32
32
|
|
33
33
|
When /^I ask for that test plan by name$/ do
|
34
|
-
@requested_test_plan_name = @server.test_plan_by_name(@original_test_plan_name
|
35
|
-
|
34
|
+
@requested_test_plan_name = @server.test_plan_by_name(@project_list.last[:name], @original_test_plan_name)
|
35
|
+
|
36
36
|
end
|
37
37
|
|
38
38
|
Then /^I get a list of projects$/ do
|
@@ -46,16 +46,16 @@ Then /^I get a list of test plans$/ do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
Then /^I get that project$/ do
|
49
|
-
@requested_test_project_name.last[
|
49
|
+
@requested_test_project_name.last[:name].should == @test_project_name
|
50
50
|
end
|
51
51
|
|
52
52
|
Then /^I get that test plan$/ do
|
53
|
-
@requested_test_plan_name.first[
|
53
|
+
@requested_test_plan_name.first[:name].should == @original_test_plan_name
|
54
54
|
end
|
55
55
|
|
56
56
|
Given /^I know the ID of a test case in that project$/ do
|
57
57
|
pending
|
58
|
-
@test_cases = @server.test_cases_for_test_plan(@test_plans.last[
|
58
|
+
@test_cases = @server.test_cases_for_test_plan(@test_plans.last[:id])
|
59
59
|
end
|
60
60
|
|
61
61
|
When /^I ask for that test case by ID$/ do
|
@@ -68,11 +68,11 @@ end
|
|
68
68
|
|
69
69
|
When /^I ask for the list of test cases in that test plan$/ do
|
70
70
|
@test_cases = @server.test_cases_for_test_plan(
|
71
|
-
@test_plans.last.values.last[
|
71
|
+
@test_plans.last.values.last[:id])
|
72
72
|
end
|
73
73
|
|
74
74
|
Then /^I get a list of test cases in that test plan$/ do
|
75
75
|
@test_cases.should_not be_nil
|
76
76
|
@test_cases.class.should == Hash
|
77
|
-
@test_cases.each_value {|v| v[
|
77
|
+
@test_cases.each_value {|v| v[:name].class.should == String }
|
78
78
|
end
|
data/features/support/env.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
if RUBY_VERSION > '1.9'
|
2
|
+
require 'simplecov'
|
3
|
+
|
4
|
+
SimpleCov.start do
|
5
|
+
add_group "Library", "lib/"
|
6
|
+
end
|
4
7
|
end
|
5
|
-
|
8
|
+
|
9
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../lib/test_linker')
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Hash
|
2
|
+
def symbolize_keys
|
3
|
+
inject({ }) do |options, (key, value)|
|
4
|
+
new_key = case key
|
5
|
+
when String
|
6
|
+
Integer(key) rescue key.to_sym
|
7
|
+
end
|
8
|
+
|
9
|
+
new_value = case value
|
10
|
+
when Hash then value.symbolize_keys
|
11
|
+
when String
|
12
|
+
Integer(value) rescue value
|
13
|
+
else value
|
14
|
+
end
|
15
|
+
|
16
|
+
options[new_key] = new_value
|
17
|
+
options
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def symbolize_keys!
|
22
|
+
self.replace(self.symbolize_keys)
|
23
|
+
end
|
24
|
+
end
|
data/lib/test_linker.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
require_relative 'test_linker/wrapper'
|
2
|
-
require_relative 'test_linker/version'
|
3
|
-
require_relative 'test_linker/error'
|
4
|
-
require_relative 'test_linker/helpers'
|
5
|
-
require 'xmlrpc/client'
|
6
1
|
require 'logger'
|
2
|
+
require 'rubygems'
|
7
3
|
require 'versionomy'
|
8
4
|
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/core_ext/hash_patch')
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_linker/wrapper')
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_linker/version')
|
8
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_linker/error')
|
9
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_linker/helpers')
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + '/core_ext/xmlrpc_client_patch')
|
11
|
+
|
9
12
|
class TestLinker
|
10
13
|
include TestLinker::Wrapper
|
11
14
|
include TestLinker::Helpers
|
@@ -77,6 +80,25 @@ class TestLinker
|
|
77
80
|
@version = Versionomy.parse(options[:version] || api_version)
|
78
81
|
end
|
79
82
|
|
83
|
+
# @return [Boolean] Returns if logging of XMLRPC requests/responses is
|
84
|
+
# enabled or not.
|
85
|
+
def log_xml?
|
86
|
+
@log_xml ||= false
|
87
|
+
end
|
88
|
+
|
89
|
+
# @param [Boolean] do_logging false to turn XMLRPC logging off; true to
|
90
|
+
# turn it back on.
|
91
|
+
def log_xml=(do_logging)
|
92
|
+
if do_logging == true
|
93
|
+
puts "WARNING: Net::HTTP warns against using this in production, so you probably shouldn't!!"
|
94
|
+
@server.set_debug(TestLinker.logger)
|
95
|
+
elsif do_logging == false
|
96
|
+
@server.set_debug(nil)
|
97
|
+
end
|
98
|
+
|
99
|
+
@log_xml = do_logging
|
100
|
+
end
|
101
|
+
|
80
102
|
# Makes the call to the server with the given arguments. Note that this also
|
81
103
|
# allows for calling XMLRPC methods on the server that haven't yet been
|
82
104
|
# implemented as Ruby methods here.
|
@@ -92,18 +114,29 @@ class TestLinker
|
|
92
114
|
# @return The return type depends on the method call.
|
93
115
|
def make_call(method_name, arguments, method_supported_in_version)
|
94
116
|
ensure_version_is :greater_than_or_equal_to, method_supported_in_version
|
117
|
+
|
118
|
+
arguments.merge!({ :devKey => @dev_key }) unless arguments.has_key? :devKey
|
119
|
+
|
95
120
|
TestLinker.log "API Version: #{method_supported_in_version}"
|
96
|
-
TestLinker.log "Calling method: '#{method_name}' with args '#{arguments}'"
|
121
|
+
TestLinker.log "Calling method: '#{method_name}' with args '#{arguments.inspect}'"
|
97
122
|
response = @server.call(method_name, arguments)
|
123
|
+
|
124
|
+
TestLinker.log "response class: #{response.class}"
|
125
|
+
if response.is_a?(Array) && response.first.is_a?(Hash)
|
126
|
+
response.each { |r| r.symbolize_keys! }
|
127
|
+
elsif response.is_a? Hash
|
128
|
+
response.symbolize_keys!
|
129
|
+
end
|
130
|
+
|
98
131
|
TestLinker.log "Received response:"
|
99
132
|
TestLinker.log response
|
100
133
|
|
101
134
|
if @version.nil?
|
102
135
|
return response
|
103
|
-
elsif response.is_a?(Array) && response.first[
|
104
|
-
raise TestLinker::Error, "#{response.first[
|
136
|
+
elsif response.is_a?(Array) && response.first[:code]
|
137
|
+
raise TestLinker::Error, "#{response.first[:code]}: #{response.first[:message]}"
|
105
138
|
end
|
106
|
-
|
139
|
+
|
107
140
|
response
|
108
141
|
end
|
109
142
|
|