test-unit 2.2.0 → 2.3.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/History.txt +24 -1
- data/Manifest.txt +8 -0
- data/README.txt +1 -0
- data/Rakefile +1 -2
- data/html/github-logo.png +0 -0
- data/html/index.html +30 -19
- data/html/index.html.ja +29 -17
- data/html/test-unit.css +9 -2
- data/lib/test/unit/assertions.rb +77 -19
- data/lib/test/unit/attribute.rb +33 -29
- data/lib/test/unit/autorunner.rb +15 -1
- data/lib/test/unit/collector/xml.rb +250 -0
- data/lib/test/unit/data.rb +80 -0
- data/lib/test/unit/error.rb +4 -3
- data/lib/test/unit/fixture.rb +30 -1
- data/lib/test/unit/runner/xml.rb +15 -0
- data/lib/test/unit/testcase.rb +201 -85
- data/lib/test/unit/testresult.rb +6 -2
- data/lib/test/unit/testsuite.rb +17 -1
- data/lib/test/unit/testsuitecreator.rb +79 -0
- data/lib/test/unit/ui/console/testrunner.rb +23 -20
- data/lib/test/unit/ui/testrunnermediator.rb +11 -2
- data/lib/test/unit/ui/xml/testrunner.rb +224 -0
- data/lib/test/unit/version.rb +1 -1
- data/test/fixtures/plus.csv +3 -0
- data/test/test-data.rb +179 -0
- data/test/test-fixture.rb +163 -0
- data/test/test-testcase.rb +49 -29
- data/test/test_testsuite.rb +19 -11
- metadata +14 -6
@@ -0,0 +1,15 @@
|
|
1
|
+
module Test
|
2
|
+
module Unit
|
3
|
+
AutoRunner.register_runner(:xml) do |auto_runner|
|
4
|
+
require 'test/unit/ui/xml/testrunner'
|
5
|
+
Test::Unit::UI::XML::TestRunner
|
6
|
+
end
|
7
|
+
|
8
|
+
AutoRunner.setup_option do |auto_runner, opts|
|
9
|
+
opts.on("--output-file-descriptor=FD", Integer,
|
10
|
+
"Outputs to file descriptor FD") do |fd|
|
11
|
+
auto_runner.runner_options[:output_file_descriptor] = fd
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/test/unit/testcase.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Author:: Nathaniel Talbott.
|
4
4
|
# Copyright::
|
5
5
|
# * Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
6
|
-
# * Copyright (c) 2008-
|
6
|
+
# * Copyright (c) 2008-2011 Kouhei Sutou <tt><kou@clear-code.com></tt>
|
7
7
|
# License:: Ruby license.
|
8
8
|
|
9
9
|
require 'test/unit/attribute'
|
@@ -16,7 +16,9 @@ require 'test/unit/pending'
|
|
16
16
|
require 'test/unit/omission'
|
17
17
|
require 'test/unit/notification'
|
18
18
|
require 'test/unit/priority'
|
19
|
+
require 'test/unit/data'
|
19
20
|
require 'test/unit/testsuite'
|
21
|
+
require 'test/unit/testsuitecreator'
|
20
22
|
require 'test/unit/assertionfailederror'
|
21
23
|
require 'test/unit/util/backtracefilter'
|
22
24
|
require 'test/unit/util/output'
|
@@ -49,6 +51,10 @@ module Test
|
|
49
51
|
# ...
|
50
52
|
# end
|
51
53
|
#
|
54
|
+
# def cleanup
|
55
|
+
# ...
|
56
|
+
# end
|
57
|
+
#
|
52
58
|
# def teardown
|
53
59
|
# ...
|
54
60
|
# end
|
@@ -66,9 +72,11 @@ module Test
|
|
66
72
|
# * startup
|
67
73
|
# * setup
|
68
74
|
# * test_my_method1
|
75
|
+
# * cleanup
|
69
76
|
# * teardown
|
70
77
|
# * setup
|
71
78
|
# * test_my_method2
|
79
|
+
# * cleanup
|
72
80
|
# * teardown
|
73
81
|
# * shutdown
|
74
82
|
class TestCase
|
@@ -81,12 +89,15 @@ module Test
|
|
81
89
|
include TestCaseOmissionSupport
|
82
90
|
include TestCaseNotificationSupport
|
83
91
|
include Priority
|
92
|
+
include Data
|
84
93
|
include Assertions
|
85
94
|
include Util::BacktraceFilter
|
86
95
|
include Util::Output
|
87
96
|
|
88
97
|
STARTED = name + "::STARTED" # :nodoc:
|
89
98
|
FINISHED = name + "::FINISHED" # :nodoc:
|
99
|
+
STARTED_OBJECT = name + "::STARTED::OBJECT" # :nodoc:
|
100
|
+
FINISHED_OBJECT = name + "::FINISHED::OBJECT" # :nodoc:
|
90
101
|
|
91
102
|
DESCENDANTS = [] # :nodoc:
|
92
103
|
AVAILABLE_ORDERS = [:alphabetic, :random, :defined] # :nodoc:
|
@@ -99,30 +110,24 @@ module Test
|
|
99
110
|
@@added_methods = {}
|
100
111
|
def method_added(name) # :nodoc:
|
101
112
|
super
|
102
|
-
|
113
|
+
_added_methods = added_methods
|
103
114
|
stringified_name = name.to_s
|
104
|
-
if
|
115
|
+
if _added_methods.include?(stringified_name)
|
105
116
|
attribute(:redefined, true, {}, stringified_name)
|
106
117
|
end
|
107
|
-
|
118
|
+
_added_methods << stringified_name
|
119
|
+
end
|
120
|
+
|
121
|
+
def added_methods # :nodoc:
|
122
|
+
@@added_methods[self] ||= []
|
108
123
|
end
|
109
124
|
|
110
125
|
# Rolls up all of the test* methods in the fixture into
|
111
126
|
# one suite, creating a new instance of the fixture for
|
112
127
|
# each method.
|
113
128
|
def suite
|
114
|
-
|
115
|
-
|
116
|
-
catch(:invalid_test) do
|
117
|
-
suite << new(test)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
if suite.empty?
|
121
|
-
catch(:invalid_test) do
|
122
|
-
suite << new("default_test")
|
123
|
-
end
|
124
|
-
end
|
125
|
-
suite
|
129
|
+
suite_creator = TestSuiteCreator.new(self)
|
130
|
+
suite_creator.create
|
126
131
|
end
|
127
132
|
|
128
133
|
# Called before every test case runs. Can be used
|
@@ -219,9 +224,11 @@ module Test
|
|
219
224
|
@@test_orders[self] = order
|
220
225
|
end
|
221
226
|
|
222
|
-
# Defines a test in declarative syntax
|
227
|
+
# Defines a test in declarative syntax or marks
|
228
|
+
# following method as a test method.
|
223
229
|
#
|
224
|
-
#
|
230
|
+
# In declarative syntax usage, the following two
|
231
|
+
# test definitions are the almost same:
|
225
232
|
#
|
226
233
|
# description "register user"
|
227
234
|
# def test_register_user
|
@@ -231,11 +238,33 @@ module Test
|
|
231
238
|
# test "register user" do
|
232
239
|
# ...
|
233
240
|
# end
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
241
|
+
#
|
242
|
+
# In test method mark usage, the "my_test_method" is
|
243
|
+
# treated as a test method:
|
244
|
+
#
|
245
|
+
# test
|
246
|
+
# def my_test_method
|
247
|
+
# assert_equal("call me", ...)
|
248
|
+
# end
|
249
|
+
def test(*test_description_or_targets, &block)
|
250
|
+
if block_given?
|
251
|
+
test_description = test_description_or_targets.first
|
252
|
+
if test_description.nil?
|
253
|
+
raise ArgumentError, "test description is missing"
|
254
|
+
end
|
255
|
+
n_arguments = test_description_or_targets.size
|
256
|
+
if n_arguments > 1
|
257
|
+
message = "wrong number of arguments (#{n_arguments} for 1)"
|
258
|
+
raise ArgumentError, message
|
259
|
+
end
|
260
|
+
method_name = test_description
|
261
|
+
define_method(method_name, &block)
|
262
|
+
description(test_description, method_name)
|
263
|
+
attribute(:test, true, {}, method_name)
|
264
|
+
else
|
265
|
+
targets = test_description_or_targets
|
266
|
+
attribute(:test, true, {}, *targets)
|
267
|
+
end
|
239
268
|
end
|
240
269
|
|
241
270
|
# Describes a test.
|
@@ -251,44 +280,6 @@ module Test
|
|
251
280
|
def description(value, target=nil)
|
252
281
|
attribute(:description, value, {}, target || [])
|
253
282
|
end
|
254
|
-
|
255
|
-
# :stopdoc:
|
256
|
-
private
|
257
|
-
def collect_test_names
|
258
|
-
method_names = public_instance_methods(true).collect do |name|
|
259
|
-
name.to_s
|
260
|
-
end
|
261
|
-
test_names = method_names.find_all do |method_name|
|
262
|
-
method_name =~ /^test./
|
263
|
-
end
|
264
|
-
send("sort_test_names_in_#{test_order}_order", test_names)
|
265
|
-
end
|
266
|
-
|
267
|
-
def sort_test_names_in_alphabetic_order(test_names)
|
268
|
-
test_names.sort
|
269
|
-
end
|
270
|
-
|
271
|
-
def sort_test_names_in_random_order(test_names)
|
272
|
-
test_names.sort_by {rand(test_names.size)}
|
273
|
-
end
|
274
|
-
|
275
|
-
def sort_test_names_in_defined_order(test_names)
|
276
|
-
added_methods = @@added_methods[self]
|
277
|
-
test_names.sort do |test1, test2|
|
278
|
-
test1_defined_order = added_methods.index(test1)
|
279
|
-
test2_defined_order = added_methods.index(test2)
|
280
|
-
if test1_defined_order and test2_defined_order
|
281
|
-
test1_defined_order <=> test2_defined_order
|
282
|
-
elsif test1_defined_order
|
283
|
-
1
|
284
|
-
elsif test2_defined_order
|
285
|
-
-1
|
286
|
-
else
|
287
|
-
test1 <=> test2
|
288
|
-
end
|
289
|
-
end
|
290
|
-
end
|
291
|
-
# :startdoc:
|
292
283
|
end
|
293
284
|
|
294
285
|
attr_reader :method_name
|
@@ -296,16 +287,29 @@ module Test
|
|
296
287
|
# Creates a new instance of the fixture for running the
|
297
288
|
# test represented by test_method_name.
|
298
289
|
def initialize(test_method_name)
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
290
|
+
@method_name = test_method_name
|
291
|
+
@internal_data = InternalData.new
|
292
|
+
end
|
293
|
+
|
294
|
+
# Assigns test data to the test. It is used in internal.
|
295
|
+
def assign_test_data(label, data) # :nodoc:
|
296
|
+
@internal_data.assign_test_data(label, data)
|
297
|
+
end
|
298
|
+
|
299
|
+
# Returns the test is valid test. It is used in internal.
|
300
|
+
def valid? # :nodoc:
|
301
|
+
return false unless respond_to?(@method_name)
|
302
|
+
test_method = method(@method_name)
|
303
|
+
if @internal_data.have_test_data?
|
304
|
+
return false unless test_method.arity == 1
|
305
|
+
else
|
306
|
+
return false unless test_method.arity <= 0
|
307
|
+
end
|
308
|
+
owner = Util::MethodOwnerFinder.find(self, @method_name)
|
303
309
|
if owner.class != Module and self.class != owner
|
304
|
-
|
310
|
+
return false
|
305
311
|
end
|
306
|
-
|
307
|
-
@test_passed = true
|
308
|
-
@interrupted = false
|
312
|
+
true
|
309
313
|
end
|
310
314
|
|
311
315
|
# Runs the individual test method represented by this
|
@@ -314,12 +318,16 @@ module Test
|
|
314
318
|
def run(result)
|
315
319
|
begin
|
316
320
|
@_result = result
|
321
|
+
@internal_data.test_started
|
317
322
|
yield(STARTED, name)
|
323
|
+
yield(STARTED_OBJECT, self)
|
318
324
|
begin
|
319
325
|
run_setup
|
320
326
|
run_test
|
327
|
+
run_cleanup
|
328
|
+
add_pass
|
321
329
|
rescue Exception
|
322
|
-
@interrupted
|
330
|
+
@internal_data.interrupted
|
323
331
|
raise unless handle_exception($!)
|
324
332
|
ensure
|
325
333
|
begin
|
@@ -328,8 +336,10 @@ module Test
|
|
328
336
|
raise unless handle_exception($!)
|
329
337
|
end
|
330
338
|
end
|
339
|
+
@internal_data.test_finished
|
331
340
|
result.add_run
|
332
341
|
yield(FINISHED, name)
|
342
|
+
yield(FINISHED_OBJECT, self)
|
333
343
|
ensure
|
334
344
|
# @_result = nil # For test-spec's after_all :<
|
335
345
|
end
|
@@ -368,6 +378,41 @@ module Test
|
|
368
378
|
def setup
|
369
379
|
end
|
370
380
|
|
381
|
+
# Called after every test method runs but the test
|
382
|
+
# method isn't marked as 'passed'. Can be used to
|
383
|
+
# clean up and/or verify tested condition.
|
384
|
+
# e.g. Can be used to verify mock.
|
385
|
+
#
|
386
|
+
# You can add additional cleanup tasks by the following
|
387
|
+
# code:
|
388
|
+
# class TestMyClass < Test::Unit::TestCase
|
389
|
+
# def cleanup
|
390
|
+
# ...
|
391
|
+
# end
|
392
|
+
#
|
393
|
+
# cleanup
|
394
|
+
# def my_cleanup1
|
395
|
+
# ...
|
396
|
+
# end
|
397
|
+
#
|
398
|
+
# cleanup
|
399
|
+
# def my_cleanup2
|
400
|
+
# ...
|
401
|
+
# end
|
402
|
+
#
|
403
|
+
# def test_my_class
|
404
|
+
# ...
|
405
|
+
# end
|
406
|
+
# end
|
407
|
+
#
|
408
|
+
# Here is a call order:
|
409
|
+
# * test_my_class
|
410
|
+
# * my_cleanup2
|
411
|
+
# * my_cleanup1
|
412
|
+
# * cleanup
|
413
|
+
def cleanup
|
414
|
+
end
|
415
|
+
|
371
416
|
# Called after every test method runs. Can be used to tear
|
372
417
|
# down fixture information.
|
373
418
|
#
|
@@ -409,10 +454,21 @@ module Test
|
|
409
454
|
1
|
410
455
|
end
|
411
456
|
|
457
|
+
# Returns a label of test data for the test. If the
|
458
|
+
# test isn't associated with any test data, it returns
|
459
|
+
# +nil+.
|
460
|
+
def data_label
|
461
|
+
@internal_data.test_data_label
|
462
|
+
end
|
463
|
+
|
412
464
|
# Returns a human-readable name for the specific test that
|
413
465
|
# this instance of TestCase represents.
|
414
466
|
def name
|
415
|
-
|
467
|
+
if @internal_data.have_test_data?
|
468
|
+
"#{@method_name}[#{data_label}](#{self.class.name})"
|
469
|
+
else
|
470
|
+
"#{@method_name}(#{self.class.name})"
|
471
|
+
end
|
416
472
|
end
|
417
473
|
|
418
474
|
# Returns a description for the test. A description
|
@@ -431,13 +487,31 @@ module Test
|
|
431
487
|
|
432
488
|
# It's handy to be able to compare TestCase instances.
|
433
489
|
def ==(other)
|
434
|
-
return false unless
|
435
|
-
return false unless
|
490
|
+
return false unless other.kind_of?(self.class)
|
491
|
+
return false unless @method_name == other.method_name
|
436
492
|
self.class == other.class
|
437
493
|
end
|
438
494
|
|
495
|
+
# Returns a Time at the test was started.
|
496
|
+
def start_time
|
497
|
+
@internal_data.start_time
|
498
|
+
end
|
499
|
+
|
500
|
+
# Returns elapsed time for the test was ran.
|
501
|
+
def elapsed_time
|
502
|
+
@internal_data.elapsed_time
|
503
|
+
end
|
504
|
+
|
505
|
+
# Returns whether the test is interrupted.
|
439
506
|
def interrupted?
|
440
|
-
@interrupted
|
507
|
+
@internal_data.interrupted?
|
508
|
+
end
|
509
|
+
|
510
|
+
# Returns whether this individual test passed or
|
511
|
+
# not. Primarily for use in teardown so that artifacts
|
512
|
+
# can be left behind if the test fails.
|
513
|
+
def passed?
|
514
|
+
@internal_data.passed?
|
441
515
|
end
|
442
516
|
|
443
517
|
private
|
@@ -446,11 +520,14 @@ module Test
|
|
446
520
|
end
|
447
521
|
|
448
522
|
def run_test
|
449
|
-
if self
|
523
|
+
if self[:redefined]
|
450
524
|
notify("#{self.class}\##{@method_name} was redefined")
|
451
525
|
end
|
452
|
-
|
453
|
-
|
526
|
+
if @internal_data.have_test_data?
|
527
|
+
__send__(@method_name, @internal_data.test_data)
|
528
|
+
else
|
529
|
+
__send__(@method_name)
|
530
|
+
end
|
454
531
|
end
|
455
532
|
|
456
533
|
def handle_exception(exception)
|
@@ -460,15 +537,8 @@ module Test
|
|
460
537
|
false
|
461
538
|
end
|
462
539
|
|
463
|
-
# Returns whether this individual test passed or
|
464
|
-
# not. Primarily for use in teardown so that artifacts
|
465
|
-
# can be left behind if the test fails.
|
466
|
-
def passed?
|
467
|
-
@test_passed
|
468
|
-
end
|
469
|
-
|
470
540
|
def problem_occurred
|
471
|
-
@
|
541
|
+
@internal_data.problem_occurred
|
472
542
|
end
|
473
543
|
|
474
544
|
def add_assertion
|
@@ -478,6 +548,52 @@ module Test
|
|
478
548
|
def add_pass
|
479
549
|
current_result.add_pass
|
480
550
|
end
|
551
|
+
|
552
|
+
class InternalData
|
553
|
+
attr_reader :start_time, :elapsed_time
|
554
|
+
attr_reader :test_data_label, :test_data
|
555
|
+
def initialize
|
556
|
+
@start_time = nil
|
557
|
+
@elapsed_time = nil
|
558
|
+
@passed = true
|
559
|
+
@interrupted = false
|
560
|
+
@test_data_label = nil
|
561
|
+
@test_data = nil
|
562
|
+
end
|
563
|
+
|
564
|
+
def passed?
|
565
|
+
@passed
|
566
|
+
end
|
567
|
+
|
568
|
+
def interrupted?
|
569
|
+
@interrupted
|
570
|
+
end
|
571
|
+
|
572
|
+
def assign_test_data(label, data)
|
573
|
+
@test_data_label = label
|
574
|
+
@test_data = data
|
575
|
+
end
|
576
|
+
|
577
|
+
def have_test_data?
|
578
|
+
not @test_data_label.nil?
|
579
|
+
end
|
580
|
+
|
581
|
+
def test_started
|
582
|
+
@start_time = Time.now
|
583
|
+
end
|
584
|
+
|
585
|
+
def test_finished
|
586
|
+
@elapsed_time = Time.now - @start_time
|
587
|
+
end
|
588
|
+
|
589
|
+
def problem_occurred
|
590
|
+
@passed = false
|
591
|
+
end
|
592
|
+
|
593
|
+
def interrupted
|
594
|
+
@interrupted = true
|
595
|
+
end
|
596
|
+
end
|
481
597
|
end
|
482
598
|
end
|
483
599
|
end
|