testability-driver-runner 0.9.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.
- data/bin/sierra +19 -0
- data/bin/tdrunner +17 -0
- data/lib/tdrunner.rb +208 -0
- data/lib/tdrunner.yml +1 -0
- data/lib/tdrunner_cucumber.rb +222 -0
- data/lib/tdrunner_cucumber_runners.rb +35 -0
- data/lib/tdrunner_file_finder.rb +45 -0
- data/lib/tdrunner_monitor.rb +473 -0
- data/lib/tdrunner_profile.rb +416 -0
- data/lib/tdrunner_test_unit.rb +433 -0
- data/rakefile +135 -0
- data/readme +186 -0
- data/websi/README +243 -0
- data/websi/Rakefile +10 -0
- data/websi/app/controllers/application_controller.rb +29 -0
- data/websi/app/controllers/report_editor/test_run/cases_controller.rb +307 -0
- data/websi/app/controllers/report_editor_controller.rb +25 -0
- data/websi/app/controllers/websi_controller.rb +478 -0
- data/websi/app/controllers/websi_script.rb +26 -0
- data/websi/app/controllers/websi_support.rb +142 -0
- data/websi/app/helpers/application_helper.rb +22 -0
- data/websi/app/helpers/report_editor/report_editor_helper.rb +26 -0
- data/websi/app/helpers/report_editor/test_run/cases_helper.rb +26 -0
- data/websi/app/helpers/websi_helper.rb +21 -0
- data/websi/app/views/layouts/application.rhtml +17 -0
- data/websi/app/views/websi/execution.html.erb +28 -0
- data/websi/app/views/websi/index.html.erb +23 -0
- data/websi/app/views/websi/profile.html.erb +30 -0
- data/websi/app/views/websi/results.html.erb +30 -0
- data/websi/app/views/websi/tests.html.erb +23 -0
- data/websi/app/views/websi/weights.html.erb +16 -0
- data/websi/config/boot.rb +129 -0
- data/websi/config/database.yml +22 -0
- data/websi/config/environment.rb +60 -0
- data/websi/config/environments/development.rb +36 -0
- data/websi/config/environments/production.rb +47 -0
- data/websi/config/environments/test.rb +47 -0
- data/websi/config/initializers/backtrace_silencers.rb +26 -0
- data/websi/config/initializers/inflections.rb +29 -0
- data/websi/config/initializers/mime_types.rb +24 -0
- data/websi/config/initializers/new_rails_defaults.rb +40 -0
- data/websi/config/initializers/session_store.rb +34 -0
- data/websi/config/locales/en.yml +5 -0
- data/websi/config/routes.rb +62 -0
- data/websi/db/development.sqlite3 +0 -0
- data/websi/db/seeds.rb +26 -0
- data/websi/doc/README_FOR_APP +2 -0
- data/websi/log/development.log +0 -0
- data/websi/log/production.log +0 -0
- data/websi/log/server.log +0 -0
- data/websi/log/test.log +0 -0
- data/websi/public/report_editor/test_run/_index.html +12 -0
- data/websi/public/robots.txt +5 -0
- data/websi/public/stylesheets/tdriver_report_style.css +220 -0
- data/websi/public/tests/config/web_profile.sip +0 -0
- data/websi/public/tests/example_profile.sip +8 -0
- data/websi/public/tests/tdrunner.yml +3 -0
- data/websi/public/tests/web_profile.sip +8 -0
- data/websi/public/tests/websi_parameters.xml +4 -0
- data/websi/script/about +4 -0
- data/websi/script/console +3 -0
- data/websi/script/dbconsole +3 -0
- data/websi/script/destroy +3 -0
- data/websi/script/generate +3 -0
- data/websi/script/performance/benchmarker +3 -0
- data/websi/script/performance/profiler +3 -0
- data/websi/script/plugin +3 -0
- data/websi/script/runner +3 -0
- data/websi/script/server +3 -0
- data/websi/test/functional/websi_controller_test.rb +27 -0
- data/websi/test/performance/browsing_test.rb +28 -0
- data/websi/test/test_helper.rb +57 -0
- data/websi/test/unit/helpers/websi_helper_test.rb +23 -0
- metadata +199 -0
@@ -0,0 +1,416 @@
|
|
1
|
+
############################################################################
|
2
|
+
##
|
3
|
+
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
## All rights reserved.
|
5
|
+
## Contact: Nokia Corporation (testabilitydriver@nokia.com)
|
6
|
+
##
|
7
|
+
## This file is part of Testability Driver.
|
8
|
+
##
|
9
|
+
## If you have questions regarding the use of this file, please contact
|
10
|
+
## Nokia at testabilitydriver@nokia.com .
|
11
|
+
##
|
12
|
+
## This library is free software; you can redistribute it and/or
|
13
|
+
## modify it under the terms of the GNU Lesser General Public
|
14
|
+
## License version 2.1 as published by the Free Software Foundation
|
15
|
+
## and appearing in the file LICENSE.LGPL included in the packaging
|
16
|
+
## of this file.
|
17
|
+
##
|
18
|
+
############################################################################
|
19
|
+
|
20
|
+
|
21
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), 'tdrunner_file_finder' ) )
|
22
|
+
require 'time'
|
23
|
+
require 'tdriver'
|
24
|
+
include TDriverReportAPI
|
25
|
+
include TDriverReportCreator
|
26
|
+
|
27
|
+
module TDRunner
|
28
|
+
#Class for loading tdrunner exeution profile from tdrunner.yml file
|
29
|
+
class TDRunnerProfileLoader
|
30
|
+
def initialize(args)
|
31
|
+
@execution_profiles=Array.new
|
32
|
+
parse_execution_profiles(args)
|
33
|
+
end
|
34
|
+
def parse_execution_profiles(args)
|
35
|
+
args.each do |value|
|
36
|
+
if value != '-p'
|
37
|
+
@execution_profiles << value.gsub(' ','')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
def args_from(profile)
|
42
|
+
unless tdrunner_yml.has_key?(profile)
|
43
|
+
raise(ProfileNotFound, <<-END_OF_ERROR)
|
44
|
+
Could not find profile: '#{profile}'
|
45
|
+
|
46
|
+
Defined profiles in tdrunner.yml:
|
47
|
+
* #{tdrunner_yml.keys.join("\n * ")}
|
48
|
+
END_OF_ERROR
|
49
|
+
end
|
50
|
+
|
51
|
+
args_from_yml = tdrunner_yml[profile] || ''
|
52
|
+
|
53
|
+
case(args_from_yml)
|
54
|
+
when String
|
55
|
+
raise YmlLoadError, "The '#{profile}' profile in tdrunner.yml was blank. Please define the command line arguments for the '#{profile}' profile in tdrunner.yml.\n" if args_from_yml =~ /^\s*$/
|
56
|
+
args_from_yml = args_from_yml.split(' ')
|
57
|
+
when Array
|
58
|
+
raise YmlLoadError, "The '#{profile}' profile in tdrunner.yml was empty. Please define the command line arguments for the '#{profile}' profile in tdrunner.yml.\n" if args_from_yml.empty?
|
59
|
+
else
|
60
|
+
raise YmlLoadError, "The '#{profile}' profile in tdrunner.yml was a #{args_from_yml.class}. It must be a String or Array"
|
61
|
+
end
|
62
|
+
args_from_yml
|
63
|
+
end
|
64
|
+
|
65
|
+
def has_profile?(profile)
|
66
|
+
tdrunner_yml.has_key?(profile)
|
67
|
+
end
|
68
|
+
|
69
|
+
def tdrunner_yml_defined?
|
70
|
+
tdrunner_file && File.exist?(tdrunner_file)
|
71
|
+
end
|
72
|
+
|
73
|
+
def get_execution_profiles
|
74
|
+
@execution_profiles
|
75
|
+
end
|
76
|
+
private
|
77
|
+
|
78
|
+
# Loads the profile, processing it through ERB and YAML, and returns it as a hash.
|
79
|
+
def tdrunner_yml
|
80
|
+
return @tdrunner_yml if @tdrunner_yml
|
81
|
+
unless tdrunner_yml_defined?
|
82
|
+
raise(ProfilesNotDefinedError,"tdrunner.yml was not found. Please refer to tdrunner's documentation on defining profiles in tdrunner.yml. You must define a 'default' profile to use the tdrunner command without any arguments.\nType 'tdrunner --help' for usage.\n")
|
83
|
+
end
|
84
|
+
|
85
|
+
require 'erb'
|
86
|
+
require 'yaml'
|
87
|
+
begin
|
88
|
+
@tdrunner_erb = ERB.new(IO.read(tdrunner_file)).result
|
89
|
+
rescue Exception => e
|
90
|
+
raise(YmlLoadError,"tdrunner.yml was found, but could not be parsed with ERB. Please refer to tdrunner's documentation on correct profile usage.\n#{$!.inspect}")
|
91
|
+
end
|
92
|
+
|
93
|
+
begin
|
94
|
+
@tdrunner_yml = YAML::load(@tdrunner_erb)
|
95
|
+
rescue Exception => e
|
96
|
+
raise(e.message,"tdrunner.yml was found, but could not be parsed. Please refer to tdrunner's documentation on correct profile usage.\n")
|
97
|
+
end
|
98
|
+
|
99
|
+
if @tdrunner_yml.nil? || !@tdrunner_yml.is_a?(Hash)
|
100
|
+
raise("tdrunner.yml was found, but was blank or malformed. Please refer to tdrunner's documentation on correct profile usage.\n")
|
101
|
+
end
|
102
|
+
|
103
|
+
return @tdrunner_yml
|
104
|
+
end
|
105
|
+
# Locates tdrunner.yml file. The file can end in .yml or .yaml,
|
106
|
+
# and be located in the current directory (eg. project root) or
|
107
|
+
# in a .config/ or config/ subdirectory of the current directory.
|
108
|
+
def tdrunner_file
|
109
|
+
@tdrunner_file ||= Dir.glob('{,.config/,config/}tdrunner{.yml,.yaml}').first
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
#Calss for holding the tdrunner execution parameters
|
114
|
+
class TDRunnerParameters
|
115
|
+
#intializes tdrunner execution parameters and loads them to memory
|
116
|
+
def initialize(args)
|
117
|
+
@test_framework=nil
|
118
|
+
@test_framework_command=Array.new
|
119
|
+
@execution_mode='-i'
|
120
|
+
@lpt_run=1
|
121
|
+
@duration_value=0
|
122
|
+
@execution_profile=nil
|
123
|
+
@tdrunner_teardown=false
|
124
|
+
@tdrunner_ordered=false
|
125
|
+
@tdrunner_combine_report=nil
|
126
|
+
@start_time=nil
|
127
|
+
@failed_execution_profile=nil
|
128
|
+
parse_tdrunner_parameters(args)
|
129
|
+
end
|
130
|
+
|
131
|
+
#method for checking the end time for tdrunner run
|
132
|
+
def format_tdrunner_date(date_time)
|
133
|
+
Time.parse(date_time)
|
134
|
+
end
|
135
|
+
|
136
|
+
#method to check that the format of the duration value is correct - e.g. 4, 4.5, 4:23 are correct
|
137
|
+
def check_duration(duration_value)
|
138
|
+
ret=false
|
139
|
+
if (/^\d+$/.match(duration_value) or /^\d+.\d+$/.match(duration_value))
|
140
|
+
ret=true
|
141
|
+
elsif (/^\d+:\d+$/.match(duration_value))
|
142
|
+
if(duration_value.split(':') [1].to_i)<60
|
143
|
+
ret=true
|
144
|
+
end
|
145
|
+
end
|
146
|
+
ret
|
147
|
+
end
|
148
|
+
|
149
|
+
#method for combining a TDriver report with the current tdrunner execution
|
150
|
+
def combine_with_existing_tdriver_report(report_location)
|
151
|
+
Kernel::raise ArgumentError.new("Report folder does not exists") if File.directory?(report_location)==false
|
152
|
+
TDriverReportAPI::tdriver_report_combine_reports(report_location)
|
153
|
+
end
|
154
|
+
|
155
|
+
#method for checking the framework command
|
156
|
+
def check_if_parameters_contain_a_framework_command(args)
|
157
|
+
parameters_contains_framework_command=false
|
158
|
+
is_directory=false
|
159
|
+
args.each do |value|
|
160
|
+
is_directory=File.directory?(value)
|
161
|
+
if value=='test_suite'
|
162
|
+
if is_directory==false
|
163
|
+
parameters_contains_framework_command=true
|
164
|
+
@test_framework='test_suite'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
if value=='test_unit'
|
168
|
+
if is_directory==false
|
169
|
+
parameters_contains_framework_command=true
|
170
|
+
@test_framework='test_unit'
|
171
|
+
end
|
172
|
+
end
|
173
|
+
if value=='cucumber'
|
174
|
+
if is_directory==false
|
175
|
+
parameters_contains_framework_command=true
|
176
|
+
@test_framework='cucumber'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
parameters_contains_framework_command
|
181
|
+
end
|
182
|
+
|
183
|
+
#Parser method for tdrunner commandline parameters
|
184
|
+
#-H prameter defines the runtime
|
185
|
+
#-d parameter is for the end time stamp
|
186
|
+
#-i parameter is for the iteration number for the tests
|
187
|
+
#-m parameter is for creating a test set execution profile without running the tests
|
188
|
+
def parse_tdrunner_parameters(args)
|
189
|
+
hour_defined=false
|
190
|
+
end_date_defined=false
|
191
|
+
start_date_defined=false
|
192
|
+
iterations_defined=false
|
193
|
+
execution_profile_defined=false
|
194
|
+
make_execution_profile=false
|
195
|
+
combine_report_defined=false
|
196
|
+
make_failed_execution_profile_defined=false
|
197
|
+
parameters_contains_framework_command=check_if_parameters_contain_a_framework_command(args)
|
198
|
+
|
199
|
+
args.each do |value|
|
200
|
+
if hour_defined==true
|
201
|
+
@execution_mode='-H'
|
202
|
+
@duration_value=value.to_s
|
203
|
+
if !check_duration(@duration_value)
|
204
|
+
puts 'Error duration '+ @duration_value+ ' is not valid!'
|
205
|
+
exit
|
206
|
+
end
|
207
|
+
hour_defined=false
|
208
|
+
end
|
209
|
+
if end_date_defined==true
|
210
|
+
@execution_mode='-d'
|
211
|
+
@lpt_run=Time.new
|
212
|
+
@lpt_run=format_tdrunner_date(value)
|
213
|
+
if @lpt_run < Time.now
|
214
|
+
puts 'Error date '+ @lpt_run.to_s + ' is in the past!'
|
215
|
+
exit
|
216
|
+
end
|
217
|
+
end_date_defined=false
|
218
|
+
end
|
219
|
+
if start_date_defined==true
|
220
|
+
@start_time=format_tdrunner_date(value)
|
221
|
+
if @start_time < Time.now
|
222
|
+
puts 'Error date '+ @start_time.to_s + ' is in the past!'
|
223
|
+
exit
|
224
|
+
end
|
225
|
+
start_date_defined=false
|
226
|
+
end
|
227
|
+
if iterations_defined==true
|
228
|
+
@execution_mode='-i'
|
229
|
+
@lpt_run=value.to_i
|
230
|
+
iterations_defined=false
|
231
|
+
end
|
232
|
+
if execution_profile_defined==true
|
233
|
+
#@execution_mode='-e'
|
234
|
+
@execution_profile=value
|
235
|
+
execution_profile_defined=false
|
236
|
+
end
|
237
|
+
if make_execution_profile==true
|
238
|
+
@execution_mode='-m'
|
239
|
+
@execution_profile=value
|
240
|
+
make_execution_profile=false
|
241
|
+
end
|
242
|
+
if combine_report_defined==true
|
243
|
+
combine_report_defined=false
|
244
|
+
@tdrunner_combine_report=value
|
245
|
+
combine_with_existing_tdriver_report(value)
|
246
|
+
end
|
247
|
+
if make_failed_execution_profile_defined==true
|
248
|
+
make_failed_execution_profile_defined=false
|
249
|
+
@failed_execution_profile=value
|
250
|
+
end
|
251
|
+
|
252
|
+
if value.to_s == '--teardown'
|
253
|
+
@tdrunner_teardown=true
|
254
|
+
end
|
255
|
+
if value.to_s == '--ordered'
|
256
|
+
@tdrunner_ordered=true
|
257
|
+
end
|
258
|
+
if value.to_s == '-H'
|
259
|
+
hour_defined=true
|
260
|
+
end
|
261
|
+
if value.to_s == '-d'
|
262
|
+
end_date_defined=true
|
263
|
+
end
|
264
|
+
if value.to_s == '-s'
|
265
|
+
start_date_defined=true
|
266
|
+
end
|
267
|
+
if value.to_s == '-i'
|
268
|
+
iterations_defined=true
|
269
|
+
end
|
270
|
+
if value.to_s == '-e'
|
271
|
+
execution_profile_defined=true
|
272
|
+
end
|
273
|
+
if value.to_s == '-m'
|
274
|
+
make_execution_profile=true
|
275
|
+
end
|
276
|
+
if value.to_s == '-c'
|
277
|
+
combine_report_defined=true
|
278
|
+
end
|
279
|
+
if value.to_s == '-t'
|
280
|
+
make_failed_execution_profile_defined=true
|
281
|
+
end
|
282
|
+
|
283
|
+
end
|
284
|
+
|
285
|
+
framework_command_start=false
|
286
|
+
args.each do |value|
|
287
|
+
if value=='.'
|
288
|
+
value=Dir.getwd
|
289
|
+
end
|
290
|
+
if framework_command_start==true
|
291
|
+
@test_framework_command << value
|
292
|
+
end
|
293
|
+
if value==@test_framework && parameters_contains_framework_command==true
|
294
|
+
framework_command_start=true
|
295
|
+
else
|
296
|
+
if File.directory?(value) && framework_command_start==false && value!=@tdrunner_combine_report
|
297
|
+
@test_framework_command << value
|
298
|
+
framework_command_start=true
|
299
|
+
end
|
300
|
+
if File.file?(value) && framework_command_start==false && value.include?('.sip')==false
|
301
|
+
@test_framework_command << value
|
302
|
+
framework_command_start=true
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
if @execution_profile!=nil
|
307
|
+
if parameters_contains_framework_command==false
|
308
|
+
profile_location=sip_file(@execution_profile,@test_framework_command)
|
309
|
+
@execution_profile=profile_location
|
310
|
+
else
|
311
|
+
profile_location=sip_file(@execution_profile)
|
312
|
+
@execution_profile=profile_location
|
313
|
+
end
|
314
|
+
end
|
315
|
+
if @failed_execution_profile!=nil
|
316
|
+
failed_profile_location=create_failed_sip(@failed_execution_profile)
|
317
|
+
@failed_execution_profile=failed_profile_location
|
318
|
+
end
|
319
|
+
end
|
320
|
+
def create_failed_sip(failed_sip_profile)
|
321
|
+
sip_file=nil
|
322
|
+
failed_sip_profile=failed_sip_profile+'.sip' if failed_sip_profile.include?('.sip')==false
|
323
|
+
#check if failed_sip_profile already exists in current dir
|
324
|
+
if File.file?(failed_sip_profile)
|
325
|
+
sip_file = failed_sip_profile
|
326
|
+
end
|
327
|
+
|
328
|
+
#check if path given
|
329
|
+
if sip_file==nil
|
330
|
+
failed_sip_profile=failed_sip_profile.gsub(/\\/,'/')
|
331
|
+
dirs = File.dirname(failed_sip_profile)
|
332
|
+
if (dirs != ".")
|
333
|
+
#check if the dirs exist, if not create the dirs
|
334
|
+
File.makedirs(dirs) if !File.exist?(dirs)
|
335
|
+
sip_file=failed_sip_profile
|
336
|
+
else
|
337
|
+
FileUtils.mkdir_p 'config' if File::directory?('config')==false
|
338
|
+
sip_file=File.join('config/', failed_sip_profile)
|
339
|
+
end
|
340
|
+
#File.open(sip_file, 'w') { |file| file.write('') }
|
341
|
+
end
|
342
|
+
|
343
|
+
return sip_file
|
344
|
+
end
|
345
|
+
# Locates sip file.
|
346
|
+
# and be located in the current directory (eg. project root) or
|
347
|
+
# in a .config/ or config/ subdirectory of the current directory.
|
348
|
+
def sip_file(tdrunner_profile,profile_folder=nil)
|
349
|
+
@tdrunner_profile_file=nil
|
350
|
+
tdrunner_profile=tdrunner_profile+'.sip' if tdrunner_profile.include?('.sip')==false
|
351
|
+
if File.file?(tdrunner_profile)
|
352
|
+
@tdrunner_profile_file=tdrunner_profile
|
353
|
+
end
|
354
|
+
|
355
|
+
if @tdrunner_profile_file==nil
|
356
|
+
profile_finder=TDRunnerFileFinder.new('sip')
|
357
|
+
found_profile_files=profile_finder.get_files(Dir.getwd)
|
358
|
+
found_profile_files.each do |profile_file|
|
359
|
+
if File.basename(profile_file.gsub('\\','/')).downcase==tdrunner_profile.downcase
|
360
|
+
@tdrunner_profile_file=profile_file.gsub('\\','/')
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
if @tdrunner_profile_file==nil
|
366
|
+
if File::directory?('config')==false
|
367
|
+
FileUtils.mkdir_p 'config'
|
368
|
+
end
|
369
|
+
if tdrunner_profile.include?("\\")
|
370
|
+
prof_arr=tdrunner_profile.split("\\")
|
371
|
+
tdrunner_profile=prof_arr.last
|
372
|
+
elsif tdrunner_profile.include?('/')
|
373
|
+
prof_arr=tdrunner_profile.split("/")
|
374
|
+
tdrunner_profile=prof_arr.last
|
375
|
+
end
|
376
|
+
File.open('config/'+tdrunner_profile, 'w') { |file| file.write('') }
|
377
|
+
profile_file=File.join('config','**', tdrunner_profile)
|
378
|
+
end
|
379
|
+
@tdrunner_profile_file ||= Dir.glob(profile_file).first
|
380
|
+
@tdrunner_profile_file
|
381
|
+
end
|
382
|
+
def test_framework()
|
383
|
+
@test_framework
|
384
|
+
end
|
385
|
+
def test_framework_command()
|
386
|
+
@test_framework_command
|
387
|
+
end
|
388
|
+
def execution_mode()
|
389
|
+
@execution_mode
|
390
|
+
end
|
391
|
+
def lpt_run()
|
392
|
+
@lpt_run
|
393
|
+
end
|
394
|
+
def duration_value()
|
395
|
+
@duration_value
|
396
|
+
end
|
397
|
+
def tdrunner_teardown()
|
398
|
+
@tdrunner_teardown
|
399
|
+
end
|
400
|
+
def execution_profile()
|
401
|
+
@execution_profile
|
402
|
+
end
|
403
|
+
def make_execution_profile()
|
404
|
+
@make_execution_profile
|
405
|
+
end
|
406
|
+
def failed_execution_profile()
|
407
|
+
@failed_execution_profile
|
408
|
+
end
|
409
|
+
def tdrunner_ordered()
|
410
|
+
@tdrunner_ordered
|
411
|
+
end
|
412
|
+
def start_time()
|
413
|
+
@start_time
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
@@ -0,0 +1,433 @@
|
|
1
|
+
##
|
2
|
+
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
3
|
+
## All rights reserved.
|
4
|
+
## Contact: Nokia Corporation (tdriversupport@nokia.com)
|
5
|
+
##
|
6
|
+
## This file is part of Testability Driver.
|
7
|
+
##
|
8
|
+
## If you have questions regarding the use of this file, please contact
|
9
|
+
## Nokia at tdriversupport@nokia.com.
|
10
|
+
##
|
11
|
+
## This library is free software; you can redistribute it and/or
|
12
|
+
## modify it under the terms of the GNU Lesser General Public
|
13
|
+
## License version 2.1 as published by the Free Software Foundation
|
14
|
+
## and appearing in the file LICENSE.LGPL included in the packaging
|
15
|
+
## of this file.
|
16
|
+
##
|
17
|
+
############################################################################
|
18
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), 'tdrunner_monitor' ) )
|
19
|
+
begin
|
20
|
+
require 'test/unit/ui/console/testrunner.rb'
|
21
|
+
require 'test/unit/util/observable'
|
22
|
+
module TDRunner
|
23
|
+
module TDRunnerTestUnit
|
24
|
+
#This class is used for building the TDRunner Test::Unit test suite
|
25
|
+
class TDRunnerTestSuiteBuilder
|
26
|
+
include TDRunner::TDRunnerMonitor
|
27
|
+
def initialize()
|
28
|
+
@exclude_folders_pattern = [ '.*', '_*' ]
|
29
|
+
@include_files_pattern = [ '*/*.rb' ]
|
30
|
+
@tests=nil
|
31
|
+
end
|
32
|
+
def file_pattern_matches?( patterns, filepath )
|
33
|
+
patterns.each{ | pattern | return true if File.fnmatch( pattern, filepath ) }; false
|
34
|
+
end
|
35
|
+
def get_files( folder, files_list = [] )
|
36
|
+
if File.directory?( folder )
|
37
|
+
folder = File.expand_path( folder )
|
38
|
+
Dir.open( folder ).each { | entry |
|
39
|
+
# create full filepath
|
40
|
+
filepath = "#{ folder }/#{ entry }"
|
41
|
+
# file: add file to required files list
|
42
|
+
files_list.push( filepath ) if file_pattern_matches?( @include_files_pattern, filepath )
|
43
|
+
# directory: go deeper in folder stack structure if exclusion pattern does not meet
|
44
|
+
files_list |= get_files("#{ filepath }/") if File.directory?( filepath ) and not file_pattern_matches?( @exclude_folders_pattern, entry )
|
45
|
+
}
|
46
|
+
files_list
|
47
|
+
else
|
48
|
+
folder
|
49
|
+
end
|
50
|
+
end
|
51
|
+
def add_file( tests )
|
52
|
+
collected_tests_and_classes=[]
|
53
|
+
@tests = []
|
54
|
+
@testcases = 0
|
55
|
+
@loaded_test_files=Array.new
|
56
|
+
tests = [ tests ] unless tests.kind_of?( Array )
|
57
|
+
tests.each{ | filename |
|
58
|
+
|
59
|
+
# expand wildcards to array if found
|
60
|
+
testsuites = ( filename.include?( '*' ) ? ( ( tmp = Dir.glob( filename ) ).empty? ? [ filename ] : tmp ): [ filename ] )
|
61
|
+
|
62
|
+
testsuites.each{ | testsuite_filename |
|
63
|
+
|
64
|
+
if File.exist?( testsuite_filename )
|
65
|
+
begin
|
66
|
+
@loaded_test_files << testsuite_filename
|
67
|
+
require testsuite_filename
|
68
|
+
rescue NoMethodError
|
69
|
+
#puts "Not a valid test unit file (#{ testsuite_filename })"
|
70
|
+
end
|
71
|
+
else
|
72
|
+
Kernel::raise LoadError.new( "Unable to add testcase to suite due to file not found (#{ testsuite_filename })" )
|
73
|
+
end
|
74
|
+
|
75
|
+
}
|
76
|
+
|
77
|
+
}
|
78
|
+
|
79
|
+
ObjectSpace.each_object( Class ){ | test_class |
|
80
|
+
if test_class.ancestors.include?( Test::Unit::TestCase ) && test_class != Test::Unit::TestCase
|
81
|
+
unless @tests.include? test_class
|
82
|
+
|
83
|
+
test_class=add_missing_methods_in_to_test_class(test_class,$tdrunner_parameters,@loaded_test_files) if $tdrunner_parameters.execution_profile!=nil
|
84
|
+
|
85
|
+
collected_tests_and_classes << test_class
|
86
|
+
test_class.public_instance_methods( true ).sort.each{ | method |
|
87
|
+
if method =~ /^test_/
|
88
|
+
collected_tests_and_classes << method+"(#{test_class})"
|
89
|
+
@testcases += 1
|
90
|
+
end
|
91
|
+
}
|
92
|
+
@tests.push test_class
|
93
|
+
end
|
94
|
+
end
|
95
|
+
}
|
96
|
+
randomize_test_cases(collected_tests_and_classes,$tdrunner_parameters)
|
97
|
+
@tests
|
98
|
+
end
|
99
|
+
end
|
100
|
+
# TDRunner test runner for Test::Unit tests
|
101
|
+
class ForkedTestRunnerMediator < Test::Unit::UI::TestRunnerMediator
|
102
|
+
require 'tdriver'
|
103
|
+
include TDRunnerMonitor
|
104
|
+
RESET = name + "::RESET"
|
105
|
+
STARTED = name + "::STARTED"
|
106
|
+
FINISHED = name + "::FINISHED"
|
107
|
+
include TDriverReportCreator
|
108
|
+
include Test::Unit::Util::Observable
|
109
|
+
|
110
|
+
# Creates a new TestRunnerMediator initialized to run
|
111
|
+
# the passed suite.
|
112
|
+
def initialize(suite)
|
113
|
+
super(suite)
|
114
|
+
trap_interrupt
|
115
|
+
@tc_result=nil
|
116
|
+
@current_suite_name=suite.name
|
117
|
+
@current_test_name=nil
|
118
|
+
add_listener(Test::Unit::TestCase::STARTED, &method(:test_started))
|
119
|
+
add_listener(Test::Unit::TestCase::FINISHED, &method(:test_finished))
|
120
|
+
add_listener(Test::Unit::TestResult::FAULT, &method(:fault))
|
121
|
+
end
|
122
|
+
|
123
|
+
# Runs the suite the TestRunnerMediator was created
|
124
|
+
# with.
|
125
|
+
def run_suite
|
126
|
+
|
127
|
+
Test::Unit.run = true
|
128
|
+
begin_time = Time.now
|
129
|
+
notify_listeners(RESET, @suite.size)
|
130
|
+
result = create_result
|
131
|
+
notify_listeners(STARTED, result)
|
132
|
+
result_listener = result.add_listener(Test::Unit::TestResult::CHANGED) do |updated_result|
|
133
|
+
notify_listeners(Test::Unit::TestResult::CHANGED, updated_result)
|
134
|
+
end
|
135
|
+
|
136
|
+
fault_listener = result.add_listener(Test::Unit::TestResult::FAULT) do |fault|
|
137
|
+
notify_listeners(Test::Unit::TestResult::FAULT, fault)
|
138
|
+
end
|
139
|
+
|
140
|
+
#SIERRA runner
|
141
|
+
run_start_time=Time.now
|
142
|
+
b_execution_monitor_thread=false
|
143
|
+
$tdrunner_interrupted=false
|
144
|
+
iteration=0
|
145
|
+
started_run()
|
146
|
+
while tdrunner_active(run_start_time,iteration,$tdrunner_parameters)==true
|
147
|
+
$tdrunner_interrupted=true if @suite.size==0
|
148
|
+
if b_execution_monitor_thread==false
|
149
|
+
b_execution_monitor_thread=true
|
150
|
+
t1 = Thread.new do
|
151
|
+
begin
|
152
|
+
while $tdrunner_interrupted==false
|
153
|
+
sleep 10
|
154
|
+
if tdrunner_active(run_start_time,iteration,$tdrunner_parameters)==false
|
155
|
+
$tdrunner_interrupted=true
|
156
|
+
end
|
157
|
+
end
|
158
|
+
rescue Exception => e
|
159
|
+
$tdrunner_interrupted=true
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
@suite.run(result) do |channel, value|
|
164
|
+
notify_listeners(channel, value)
|
165
|
+
break if $tdrunner_interrupted==true
|
166
|
+
end
|
167
|
+
iteration+=1
|
168
|
+
break if $tdrunner_interrupted==true
|
169
|
+
end
|
170
|
+
iteration=0
|
171
|
+
$tdrunner_interrupted=true
|
172
|
+
puts "\n"
|
173
|
+
current_run_time=Time.now-run_start_time
|
174
|
+
puts 'Run time: '+ format_duration(current_run_time)
|
175
|
+
#end SIERRA runner
|
176
|
+
|
177
|
+
result.remove_listener(Test::Unit::TestResult::FAULT, fault_listener)
|
178
|
+
result.remove_listener(Test::Unit::TestResult::CHANGED, result_listener)
|
179
|
+
end_time = Time.now
|
180
|
+
elapsed_time = end_time - begin_time
|
181
|
+
notify_listeners(FINISHED, elapsed_time) #"Finished in #{elapsed_time} seconds.")
|
182
|
+
return result
|
183
|
+
end
|
184
|
+
def get_class_name(full_test_name) #:nodoc:
|
185
|
+
begin
|
186
|
+
name=full_test_name
|
187
|
+
name=name.gsub(/[)]/,'')
|
188
|
+
name_arr=name.split('(')
|
189
|
+
return [name_arr[1].gsub(/[:]/,'_'),name_arr[0].gsub(/[:]/,'_')]
|
190
|
+
rescue
|
191
|
+
return ['Ruby test',full_test_name]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
#This method initializes new test run
|
195
|
+
#
|
196
|
+
# === params
|
197
|
+
# === returns
|
198
|
+
# === raises
|
199
|
+
def started_run()
|
200
|
+
start_run()
|
201
|
+
add_report_group(@current_suite_name+'|')
|
202
|
+
end
|
203
|
+
#This method starts a new test case
|
204
|
+
#
|
205
|
+
# === params
|
206
|
+
# === returns
|
207
|
+
# === raises
|
208
|
+
def test_started(name)
|
209
|
+
full_name=get_class_name(name)
|
210
|
+
@current_test_name=full_name[1]
|
211
|
+
add_report_group(@current_suite_name+':'+full_name[0]+'|')
|
212
|
+
start_test_case(@current_test_name)
|
213
|
+
add_test_case_group(full_name[0])
|
214
|
+
@tc_result='passed'
|
215
|
+
end
|
216
|
+
#This method records the test case result
|
217
|
+
#
|
218
|
+
# === params
|
219
|
+
# === returns
|
220
|
+
# === raises
|
221
|
+
def test_finished(name)
|
222
|
+
if @tc_result=='passed'
|
223
|
+
update_test_case('-')
|
224
|
+
end
|
225
|
+
end_test_case(@current_test_name,@tc_result)
|
226
|
+
end
|
227
|
+
#This method records the test case fault result
|
228
|
+
#
|
229
|
+
# === params
|
230
|
+
# === returns
|
231
|
+
# === raises
|
232
|
+
def fault(fault)
|
233
|
+
capture_screen_test_case()
|
234
|
+
update_test_case(fault)
|
235
|
+
@tc_result='failed'
|
236
|
+
end
|
237
|
+
private
|
238
|
+
# A factory method to create the result the mediator
|
239
|
+
# should run with. Can be overridden by subclasses if
|
240
|
+
# one wants to use a different result.
|
241
|
+
def create_result
|
242
|
+
return Test::Unit::TestResult.new
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
#This class replaces the original Test::Unit runnerr with TDRunner runner and tdriver reporting
|
247
|
+
class TDRunnerTestUnitRunner < Test::Unit::UI::Console::TestRunner
|
248
|
+
def run(suite, output_level=NORMAL)
|
249
|
+
return new(suite, output_level).start
|
250
|
+
end
|
251
|
+
def create_mediator(suite)
|
252
|
+
return ForkedTestRunnerMediator.new(suite)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
#This class initializes TDRunner for Test::Unit
|
257
|
+
class ForkedTestUnitRunner
|
258
|
+
include TDRunnerMonitor
|
259
|
+
# Creates a new TestRunner and runs the suite.
|
260
|
+
def initialize(test_suite)
|
261
|
+
results=TDRunnerTestUnitRunner.run(test_suite)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
module Test
|
267
|
+
module Unit
|
268
|
+
class TestCase
|
269
|
+
# Runs the individual test method represented by this
|
270
|
+
# instance of the fixture, collecting statistics, failures
|
271
|
+
# and errors in result.
|
272
|
+
def run(result,arguments=nil,case_contents_array=nil,current_index=nil,status=nil)
|
273
|
+
@test_passed=true
|
274
|
+
yield(STARTED, name)
|
275
|
+
@_result = result
|
276
|
+
@case_contents_array=case_contents_array
|
277
|
+
begin
|
278
|
+
|
279
|
+
if self.respond_to?("setup_#{name[0..(name.to_s.index('(')-1)]}")
|
280
|
+
__send__("setup_#{name[0..(name.to_s.index('(')-1)]}") if status!=false
|
281
|
+
else
|
282
|
+
setup if status!=false
|
283
|
+
end
|
284
|
+
|
285
|
+
if arguments!=nil && status==nil
|
286
|
+
__send__(@method_name,*arguments)
|
287
|
+
elsif status==false
|
288
|
+
Kernel::raise('Previous dependency test failed')
|
289
|
+
else
|
290
|
+
__send__(@method_name)
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
rescue AssertionFailedError => e
|
295
|
+
add_failure(e.message, e.backtrace)
|
296
|
+
rescue Exception
|
297
|
+
raise if PASSTHROUGH_EXCEPTIONS.include? $!.class
|
298
|
+
add_error($!)
|
299
|
+
ensure
|
300
|
+
begin
|
301
|
+
if $tdrunner_parameters.tdrunner_teardown==true
|
302
|
+
if @test_passed != true
|
303
|
+
if respond_to?("teardown_#{name[0..(name.to_s.index('(')-1)]}")
|
304
|
+
__send__("teardown_#{name[0..(name.to_s.index('(')-1)]}") if status!=false
|
305
|
+
else
|
306
|
+
teardown if status!=false
|
307
|
+
end
|
308
|
+
end
|
309
|
+
else
|
310
|
+
if respond_to?("teardown_#{name[0..(name.to_s.index('(')-1)]}")
|
311
|
+
__send__("teardown_#{name[0..(name.to_s.index('(')-1)]}") if status!=false
|
312
|
+
else
|
313
|
+
teardown if status!=false
|
314
|
+
end
|
315
|
+
end
|
316
|
+
rescue AssertionFailedError => e
|
317
|
+
add_failure(e.message, e.backtrace)
|
318
|
+
rescue Exception
|
319
|
+
raise if PASSTHROUGH_EXCEPTIONS.include? $!.class
|
320
|
+
add_error($!)
|
321
|
+
end
|
322
|
+
@case_contents_array[current_index]=[@case_contents_array[current_index].at(0),@case_contents_array[current_index].at(1),@case_contents_array[current_index].at(2),@test_passed] if @case_contents_array!=nil && status==nil
|
323
|
+
end
|
324
|
+
result.add_run
|
325
|
+
yield(FINISHED, name)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
class TestSuite
|
329
|
+
include TDRunner::TDRunnerMonitor
|
330
|
+
# Runs the tests and/or suites contained in this
|
331
|
+
# TestSuite.
|
332
|
+
def parse_parameter_string(string)
|
333
|
+
s = string
|
334
|
+
|
335
|
+
separator = '%separator%'
|
336
|
+
|
337
|
+
strings = []
|
338
|
+
|
339
|
+
# store strings
|
340
|
+
s.scan( /(["'])(.*?\1)/ ).each_with_index{ | match, index |
|
341
|
+
|
342
|
+
strings << match.join
|
343
|
+
|
344
|
+
s.gsub!( strings.last, "%string#{ index }%" )
|
345
|
+
|
346
|
+
}
|
347
|
+
|
348
|
+
s.gsub!( ',', separator )
|
349
|
+
|
350
|
+
# return string
|
351
|
+
strings.each_with_index{ | string, index |
|
352
|
+
|
353
|
+
s.gsub!( "%string#{ index }%", string )
|
354
|
+
}
|
355
|
+
|
356
|
+
parameters = s.split( separator )
|
357
|
+
parameters
|
358
|
+
end
|
359
|
+
def run(result,arguments=nil,case_contents_array=nil, current_index=nil,status=nil, &progress_block)
|
360
|
+
yield(STARTED, name)
|
361
|
+
@tests,@case_contents_array=randomize_test_cases(@tests,$tdrunner_parameters)
|
362
|
+
@test_level_and_result=Array.new if @test_level_and_result==nil
|
363
|
+
current_index=0
|
364
|
+
previous_test_level=0
|
365
|
+
previous_test_level_result=nil
|
366
|
+
current_test_level=0
|
367
|
+
@tests.each do |test|
|
368
|
+
parameters_arr=nil
|
369
|
+
eval_parameters_arr=[]
|
370
|
+
if @case_contents_array!=nil
|
371
|
+
if @case_contents_array[current_index]!=nil
|
372
|
+
parameters_arr=parse_parameter_string(@case_contents_array[current_index].at(1)) if @case_contents_array[current_index].at(1)!=nil
|
373
|
+
previous_test_level=@case_contents_array[current_index-1].at(2).count "-" if current_index > 0
|
374
|
+
previous_test_level_result=@case_contents_array[current_index-1].at(3) if current_index > 0
|
375
|
+
@test_level_and_result << [previous_test_level,previous_test_level_result]
|
376
|
+
current_test_level=@case_contents_array[current_index].at(2).count "-"
|
377
|
+
@test_level_and_result=[] if current_test_level==0
|
378
|
+
if parameters_arr!=nil
|
379
|
+
parameters_arr.each do |sip_parameter|
|
380
|
+
eval_result=eval(sip_parameter)
|
381
|
+
eval_parameters_arr.push eval_result if eval_result!=nil
|
382
|
+
end
|
383
|
+
end
|
384
|
+
#execution logic for running tests with dependency
|
385
|
+
#case contents array contains "test case name, test case parameters, test case position in tree, test case result"
|
386
|
+
if $tdrunner_parameters.tdrunner_ordered==true
|
387
|
+
b_dependency_passed=true
|
388
|
+
first_failed_test_level_fail=0
|
389
|
+
first_test_level_pass=0
|
390
|
+
@test_level_and_result.each do |test_level_result|
|
391
|
+
if test_level_result[1]==false
|
392
|
+
first_failed_test_level_fail=test_level_result[0]
|
393
|
+
if first_failed_test_level_fail.to_i<current_test_level.to_i
|
394
|
+
b_dependency_passed=false
|
395
|
+
end
|
396
|
+
elsif test_level_result[1]==true
|
397
|
+
first_test_level_pass=test_level_result[0]
|
398
|
+
if first_test_level_pass.to_i<current_test_level.to_i
|
399
|
+
b_dependency_passed=true
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
if current_test_level==0
|
405
|
+
test.run(result, eval_parameters_arr, @case_contents_array, current_index, nil, &progress_block)
|
406
|
+
elsif b_dependency_passed==false
|
407
|
+
test.run(result, eval_parameters_arr, @case_contents_array, current_index, false, &progress_block)
|
408
|
+
elsif b_dependency_passed==true
|
409
|
+
test.run(result, eval_parameters_arr, @case_contents_array, current_index, nil, &progress_block)
|
410
|
+
else
|
411
|
+
test.run(result, eval_parameters_arr, @case_contents_array, current_index, false, &progress_block)
|
412
|
+
end
|
413
|
+
else
|
414
|
+
test.run(result, eval_parameters_arr, @case_contents_array, current_index, nil, &progress_block)
|
415
|
+
end
|
416
|
+
end
|
417
|
+
else
|
418
|
+
test.run(result, eval_parameters_arr, @case_contents_array, current_index, &progress_block)
|
419
|
+
end
|
420
|
+
|
421
|
+
if (@case_contents_array!=nil && @case_contents_array[current_index]!=nil && @case_contents_array[current_index].at(3)==false)
|
422
|
+
add_failed_testunit_tests($tdrunner_parameters, @case_contents_array, current_index)
|
423
|
+
end
|
424
|
+
current_index+=1
|
425
|
+
end
|
426
|
+
yield(FINISHED, name)
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|
431
|
+
rescue LoadError
|
432
|
+
|
433
|
+
end
|