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