Class: Test::Unit::TestCase
- Inherits:
-
Object
- Object
- Test::Unit::TestCase
- Includes:
- Assertions, Attribute, Data, ErrorHandler, ExceptionHandler, FailureHandler, Fixture, Priority, TestCaseNotificationSupport, TestCaseOmissionSupport, TestCasePendingSupport, Util::BacktraceFilter, Util::Output
- Defined in:
- lib/test/unit/testcase.rb
Overview
Ties everything together. If you subclass and add your own test methods, it takes care of making them into tests and wrapping those tests into a suite. It also does the nitty-gritty of actually running an individual test and collecting its results into a Test::Unit::TestResult object.
You can run two hooks before/after a TestCase run.
Example:
class TestMyClass < Test::Unit::TestCase
class << self
def startup
...
end
def shutdown
...
end
end
def setup
...
end
def cleanup
...
end
def teardown
...
end
def test_my_method1
...
end
def test_my_method2
...
end
end
Here is a call order:
-
startup
-
setup
-
test_my_method1
-
cleanup
-
teardown
-
setup
-
test_my_method2
-
cleanup
-
teardown
-
shutdown
You can set an attribute to each test.
Example:
class TestMyClass < Test::Unit::TestCase
attribute :speed, :fast
def test_my_fast_method
# You can get the attribute via `self[]`
self[:speed] # => :fast
...
end
attribute :speed, :slow
def test_my_slow_method
self[:speed] # => :slow
...
end
end
Defined Under Namespace
Classes: InternalData
Constant Summary collapse
- STARTED =
:nodoc:
name + "::STARTED"
- FINISHED =
:nodoc:
name + "::FINISHED"
- STARTED_OBJECT =
:nodoc:
name + "::STARTED::OBJECT"
- FINISHED_OBJECT =
:nodoc:
name + "::FINISHED::OBJECT"
- DESCENDANTS =
:nodoc:
[]
- AVAILABLE_ORDERS =
:nodoc:
[:alphabetic, :random, :defined]
- @@added_method_names =
{}
- @@test_orders =
{}
Constants included from Util::BacktraceFilter
Util::BacktraceFilter::POWERASSERT_PREFIX, Util::BacktraceFilter::TESTUNIT_FILE_SEPARATORS, Util::BacktraceFilter::TESTUNIT_PREFIX, Util::BacktraceFilter::TESTUNIT_RB_FILE
Constants included from Assertions
Constants included from ErrorHandler
ErrorHandler::NOT_PASS_THROUGH_EXCEPTIONS, ErrorHandler::NOT_PASS_THROUGH_EXCEPTION_NAMES, ErrorHandler::PASS_THROUGH_EXCEPTIONS, ErrorHandler::PASS_THROUGH_EXCEPTION_NAMES
Instance Attribute Summary collapse
-
#method_name ⇒ Object
readonly
Returns the value of attribute method_name.
Class Method Summary collapse
-
.added_method_names ⇒ Object
:nodoc:.
-
.description(value, target = nil) ⇒ Object
Describes a test.
- .find_locations(query) ⇒ Object
-
.include(*modules, &block) ⇒ Object
:nodoc:.
-
.inherited(sub_class) ⇒ Object
:nodoc:.
-
.method_added(name) ⇒ Object
:nodoc:.
-
.parallel_safe? ⇒ Boolean
Indicates whether the test is parallel safe.
-
.ractor(options = {}) ⇒ void
Declares that the following test uses Ractor.
-
.shutdown ⇒ Object
Called after every test case runs.
-
.startup ⇒ Object
Called before every test case runs.
-
.sub_test_case(name) { ... } ⇒ Test::Unit::TestCase
Defines a sub test case.
-
.suite ⇒ Object
Rolls up all of the test* methods in the fixture into one suite, creating a new instance of the fixture for each method.
-
.test(*test_description_or_targets, &block) ⇒ Object
Defines a test in declarative syntax or marks following method as a test method.
-
.test_defined?(query) ⇒ Boolean
Checks whether a test that is matched the query is defined.
-
.test_order ⇒ Object
Returns the current test order.
-
.test_order=(order) ⇒ Object
Sets the current test order.
Instance Method Summary collapse
-
#==(other) ⇒ Object
It’s handy to be able to compare TestCase instances.
-
#add_pass ⇒ void
Notify that the test is passed.
-
#assign_test_data(label, data) ⇒ Object
Assigns test data to the test.
-
#cleanup ⇒ Object
Called after every test method runs but the test method isn’t marked as ‘passed’.
-
#data ⇒ Object
Returns test data for the test.
-
#data_label ⇒ Object
Returns a label of test data for the test.
- #default_test ⇒ Object
-
#description ⇒ Object
Returns a description for the test.
-
#elapsed_time ⇒ Object
Returns elapsed time for the test was ran.
-
#initialize(test_method_name) ⇒ TestCase
constructor
Creates a new instance of the fixture for running the test represented by test_method_name.
-
#interrupted? ⇒ Boolean
Returns whether the test is interrupted.
-
#local_name ⇒ Object
Returns a human-readable name for the specific test that this instance of TestCase represents.
-
#name ⇒ Object
Returns a human-readable name for the specific test that this instance of TestCase represents.
-
#passed? ⇒ Boolean
Returns whether this individual test passed or not.
-
#problem_occurred ⇒ void
Notify that a problem is occurred in the test.
-
#run(result, runner_class: nil) ⇒ Object
Runs the individual test method represented by this instance of the fixture, collecting statistics, failures and errors in result.
-
#setup ⇒ Object
Called before every test method runs.
- #size ⇒ Object
-
#start_time ⇒ Object
Returns a Time at the test was started.
-
#teardown ⇒ Object
Called after every test method runs.
-
#to_s ⇒ Object
Overridden to return #name.
-
#valid? ⇒ Boolean
Returns the test is valid test.
Methods included from Util::Output
Methods included from Util::BacktraceFilter
Methods included from Assertions
#assert, #assert_alias_method, #assert_all, #assert_block, #assert_boolean, #assert_compare, #assert_const_defined, #assert_empty, #assert_equal, #assert_fail_assertion, #assert_false, #assert_in_delta, #assert_in_epsilon, #assert_include, #assert_instance_of, #assert_kind_of, #assert_match, #assert_nil, #assert_no_match, #assert_not_const_defined, #assert_not_empty, #assert_not_equal, #assert_not_in_delta, #assert_not_in_epsilon, #assert_not_include, #assert_not_instance_of, #assert_not_kind_of, #assert_not_match, #assert_not_nil, #assert_not_operator, #assert_not_predicate, #assert_not_respond_to, #assert_not_same, #assert_not_send, #assert_nothing_leaked_memory, #assert_nothing_raised, #assert_nothing_thrown, #assert_operator, #assert_path_exist, #assert_path_not_exist, #assert_predicate, #assert_raise, #assert_raise_kind_of, #assert_raise_message, #assert_raise_with_message, #assert_respond_to, #assert_same, #assert_send, #assert_throw, #assert_true, #build_message, #flunk, #refute, use_pp=
Methods included from Data
Methods included from Priority
available_values, default, default=, disable, enable, enabled?, included, #priority_setup, #priority_teardown
Methods included from TestCaseNotificationSupport
Methods included from TestCaseOmissionSupport
included, #omit, #omit_if, #omit_unless
Methods included from TestCasePendingSupport
Methods included from FailureHandler
Methods included from ErrorHandler
Methods included from ExceptionHandler
Methods included from Fixture
Methods included from Attribute
Constructor Details
#initialize(test_method_name) ⇒ TestCase
Creates a new instance of the fixture for running the test represented by test_method_name.
553 554 555 556 |
# File 'lib/test/unit/testcase.rb', line 553 def initialize(test_method_name) @method_name = test_method_name @internal_data = InternalData.new end |
Instance Attribute Details
#method_name ⇒ Object (readonly)
Returns the value of attribute method_name.
549 550 551 |
# File 'lib/test/unit/testcase.rb', line 549 def method_name @method_name end |
Class Method Details
.added_method_names ⇒ Object
:nodoc:
198 199 200 |
# File 'lib/test/unit/testcase.rb', line 198 def added_method_names # :nodoc: (@@added_method_names[self] ||= {}).keys end |
.description(value, target = nil) ⇒ Object
Describes a test.
The following example associates “register a normal user” description with “test_register” test.
description "register a normal user"
def test_register
...
end
374 375 376 377 |
# File 'lib/test/unit/testcase.rb', line 374 def description(value, target=nil) targets = [target].compact attribute(:description, value, {}, *targets) end |
.find_locations(query) ⇒ Object
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 |
# File 'lib/test/unit/testcase.rb', line 466 def find_locations(query) query_path = query[:path] query_line = query[:line] query_method_name = query[:method_name] available_locations = target_method_locations(query_path) if query_line available_locations = available_locations.sort_by do |location| -location[:line] end available_location = available_locations.find do |location| query_line >= location[:line] end return [] if available_location.nil? return [] if available_location[:test_case] != self available_locations = [available_location] end if query_method_name available_location = available_locations.find do |location| location[:test_case] == self and query_method_name == location[:method_name] end return [] if available_location.nil? available_locations = [available_location] end available_locations end |
.include(*modules, &block) ⇒ Object
:nodoc:
158 159 160 161 162 163 164 165 166 |
# File 'lib/test/unit/testcase.rb', line 158 def include(*modules, &block) # :nodoc: result = super modules.each do |mod| mod.public_instance_methods(false).each do |method_name| AutoRunnerLoader.check(self, method_name.to_s) end end result end |
.inherited(sub_class) ⇒ Object
:nodoc:
153 154 155 156 |
# File 'lib/test/unit/testcase.rb', line 153 def inherited(sub_class) # :nodoc: DESCENDANTS << sub_class super end |
.method_added(name) ⇒ Object
:nodoc:
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/test/unit/testcase.rb', line 169 def method_added(name) # :nodoc: super added_method_names = (@@added_method_names[self] ||= {}) stringified_name = name.to_s if added_method_names.key?(stringified_name) attribute(:redefined, {:backtrace => caller}, {}, stringified_name) end source_location = find_attribute(stringified_name, :source_location) if source_location path, line = source_location elsif respond_to?(:caller_locations, true) location = caller_locations(1, 1)[0] path = location.absolute_path || location.path line = location.lineno else # TODO: Remove me when Ruby 1.9 support is dropped path, line, = caller[0].split(/:(\d+)/, 2) line = line.to_i if line end location = { :method_name => stringified_name, :path => File.(path), :line => line, } add_method_location(location) added_method_names[stringified_name] = true AutoRunnerLoader.check(self, stringified_name) end |
.parallel_safe? ⇒ Boolean
Indicates whether the test is parallel safe.
Tests that this method returns ‘false` are executed sequentially before parallel safe tests run. This only works when the `–parallel` option is specified.
149 150 151 |
# File 'lib/test/unit/testcase.rb', line 149 def parallel_safe? true end |
.ractor(options = {}) ⇒ void
This method returns an undefined value.
Declares that the following test uses Ractor.
Tests that use Ractor are executed at the end. Because multi Ractor mode is enabled in the current process and it’s not disabled even when only one Ractor is running after running a test that uses Ractor on Ruby 3.0. It will be solved in the future.
This is implemented by setting the ‘:ractor` attribute of the test to `true`.
405 406 407 |
# File 'lib/test/unit/testcase.rb', line 405 def ractor(={}) attribute(:ractor, true, ) end |
.shutdown ⇒ Object
Called after every test case runs. Can be used to tear down fixture information used in test case scope.
Here is an example test case:
class TestMyClass < Test::Unit::TestCase
class << self
def shutdown
...
end
end
def teardown
...
end
def test_my_class1
...
end
def test_my_class2
...
end
end
Here is a call order:
-
test_my_class1 (or test_my_class2)
-
teardown
-
test_my_class2 (or test_my_class1)
-
teardown
-
shutdown
Note that you should not assume test order. Tests should be worked in any order.
284 285 |
# File 'lib/test/unit/testcase.rb', line 284 def shutdown end |
.startup ⇒ Object
Called before every test case runs. Can be used to set up fixture information used in test case scope.
Here is an example test case:
class TestMyClass < Test::Unit::TestCase
class << self
def startup
...
end
end
def setup
...
end
def test_my_class1
...
end
def test_my_class2
...
end
end
Here is a call order:
-
startup
-
setup
-
test_my_class1 (or test_my_class2)
-
setup
-
test_my_class2 (or test_my_class1)
Note that you should not assume test order. Tests should be worked in any order.
246 247 |
# File 'lib/test/unit/testcase.rb', line 246 def startup end |
.sub_test_case(name) { ... } ⇒ Test::Unit::TestCase
Defines a sub test case.
This is a syntax sugar. The both of the following codes are the same in meaning:
Standard:
class TestParent < Test::Unit::TestCase
class TestChild < self
def test_in_child
end
end
end
Syntax sugar:
class TestParent < Test::Unit::TestCase
sub_test_case("TestChild") do
def test_in_child
end
end
end
The difference of them are the following:
-
Test case created by sub_test_case is an anonymous class. So you can’t refer the test case by name.
-
The class name of class style must follow constant naming rule in Ruby. But the name of test case created by sub_test_case doesn’t need to follow the rule. For example, you can use a space in name such as “child test”.
446 447 448 449 450 |
# File 'lib/test/unit/testcase.rb', line 446 def sub_test_case(name, &block) sub_test_case = sub_test_case_class(name) sub_test_case.class_eval(&block) sub_test_case end |
.suite ⇒ Object
Rolls up all of the test* methods in the fixture into one suite, creating a new instance of the fixture for each method.
205 206 207 208 |
# File 'lib/test/unit/testcase.rb', line 205 def suite suite_creator = TestSuiteCreator.new(self) suite_creator.create end |
.test(*test_description_or_targets, &block) ⇒ Object
Defines a test in declarative syntax or marks following method as a test method.
In declarative syntax usage, the following two test definitions are the almost same:
description "register user"
def test_register_user
...
end
test "register user" do
...
end
In test method mark usage, the “my_test_method” is treated as a test method:
test
def my_test_method
assert_equal("call me", ...)
end
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/test/unit/testcase.rb', line 337 def test(*test_description_or_targets, &block) if block_given? test_description = test_description_or_targets.first if test_description.nil? raise ArgumentError, "test description is missing" end n_arguments = test_description_or_targets.size if n_arguments > 1 = "wrong number of arguments (#{n_arguments} for 1)" raise ArgumentError, end method_name = "test: #{test_description}" description(test_description, method_name) attribute(:test, true, {}, method_name) if block.respond_to?(:source_location) attribute(:source_location, block.source_location, {}, method_name) end define_method(method_name, &block) else targets = test_description_or_targets attribute(:test, true, {}, *targets) targets.each do |target| AutoRunnerLoader.check(self, target) end end end |
.test_defined?(query) ⇒ Boolean
Checks whether a test that is matched the query is defined.
461 462 463 464 |
# File 'lib/test/unit/testcase.rb', line 461 def test_defined?(query) locations = find_locations(query) not locations.empty? end |
.test_order ⇒ Object
Returns the current test order. This returns ‘:alphabetic` by default.
291 292 293 294 295 296 297 |
# File 'lib/test/unit/testcase.rb', line 291 def test_order ancestors.each do |ancestor| order = @@test_orders[ancestor] return order if order end AVAILABLE_ORDERS.first end |
.test_order=(order) ⇒ Object
Sets the current test order.
Here are the available order:
:alphabetic : Default. Tests are sorted in alphabetic order.
:random : Tests are sorted in random order.
:defined : Tests are sorted in defined order.
311 312 313 |
# File 'lib/test/unit/testcase.rb', line 311 def test_order=(order) @@test_orders[self] = order end |
Instance Method Details
#==(other) ⇒ Object
It’s handy to be able to compare TestCase instances.
819 820 821 822 823 824 |
# File 'lib/test/unit/testcase.rb', line 819 def ==(other) return false unless other.kind_of?(self.class) return false unless @method_name == other.method_name return false unless data_label == other.data_label self.class == other.class end |
#add_pass ⇒ void
This method returns an undefined value.
Notify that the test is passed. Normally, it is not needed because #run calls it automatically. If you want to override #run, it is not a good idea. Please contact test-unit developers. We will help you without your custom #run. For example, we may add a new hook in #run.
This is a public API for developers who extend test-unit.
868 869 870 |
# File 'lib/test/unit/testcase.rb', line 868 def add_pass current_result.add_pass end |
#assign_test_data(label, data) ⇒ Object
Assigns test data to the test. It is used in internal.
559 560 561 |
# File 'lib/test/unit/testcase.rb', line 559 def assign_test_data(label, data) # :nodoc: @internal_data.assign_test_data(label, data) end |
#cleanup ⇒ Object
Called after every test method runs but the test method isn’t marked as ‘passed’. Can be used to clean up and/or verify tested condition. e.g. Can be used to verify mock.
You can add additional cleanup tasks by the following code:
class TestMyClass < Test::Unit::TestCase
def cleanup
...
end
cleanup
def my_cleanup1
...
end
cleanup do
... # cleanup callback1
end
cleanup
def my_cleanup2
...
end
cleanup do
... # cleanup callback2
end
def test_my_class
...
end
end
Here is a call order:
-
test_my_class
-
cleanup callback2
-
my_cleanup2
-
cleanup callback1
-
my_cleanup1
-
cleanup
716 717 |
# File 'lib/test/unit/testcase.rb', line 716 def cleanup end |
#data ⇒ Object
Returns test data for the test. If the test isn’t associated with any test data, it returns ‘nil`.
781 782 783 |
# File 'lib/test/unit/testcase.rb', line 781 def data @internal_data.test_data end |
#data_label ⇒ Object
Returns a label of test data for the test. If the test isn’t associated with any test data, it returns ‘nil`.
775 776 777 |
# File 'lib/test/unit/testcase.rb', line 775 def data_label @internal_data.test_data_label end |
#default_test ⇒ Object
764 765 766 |
# File 'lib/test/unit/testcase.rb', line 764 def default_test flunk("No tests were specified") end |
#description ⇒ Object
Returns a description for the test. A description will be associated by Test::Unit::TestCase.test or Test::Unit::TestCase.description.
Returns a name for the test for no description test.
809 810 811 |
# File 'lib/test/unit/testcase.rb', line 809 def description self[:description] || name end |
#elapsed_time ⇒ Object
Returns elapsed time for the test was ran.
832 833 834 |
# File 'lib/test/unit/testcase.rb', line 832 def elapsed_time @internal_data.elapsed_time end |
#interrupted? ⇒ Boolean
Returns whether the test is interrupted.
837 838 839 |
# File 'lib/test/unit/testcase.rb', line 837 def interrupted? @internal_data.interrupted? end |
#local_name ⇒ Object
Returns a human-readable name for the specific test that this instance of TestCase represents.
‘#local_name` doesn’t include class name. ‘#name` includes class name.
796 797 798 799 800 801 802 |
# File 'lib/test/unit/testcase.rb', line 796 def local_name if @internal_data.have_test_data? "#{@method_name}[#{data_label}]" else @method_name.to_s end end |
#name ⇒ Object
Returns a human-readable name for the specific test that this instance of TestCase represents.
787 788 789 |
# File 'lib/test/unit/testcase.rb', line 787 def name "#{local_name}(#{self.class.name})" end |
#passed? ⇒ Boolean
Returns whether this individual test passed or not. Primarily for use in teardown so that artifacts can be left behind if the test fails.
844 845 846 |
# File 'lib/test/unit/testcase.rb', line 844 def passed? @internal_data.passed? end |
#problem_occurred ⇒ void
This method returns an undefined value.
Notify that a problem is occurred in the test. It means that the test is a failed test. If any failed tests exist in test suites, the test process exits with failure exit status.
This is a public API for developers who extend test-unit.
855 856 857 |
# File 'lib/test/unit/testcase.rb', line 855 def problem_occurred @internal_data.problem_occurred end |
#run(result, runner_class: nil) ⇒ Object
Runs the individual test method represented by this instance of the fixture, collecting statistics, failures and errors in result.
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 |
# File 'lib/test/unit/testcase.rb', line 580 def run(result, runner_class: nil) begin @_result = result @internal_data.test_started yield(STARTED, name) yield(STARTED_OBJECT, self) processed_exception_in_setup = false begin catch do |tag| run_setup do begin run_test run_cleanup add_pass rescue Exception @internal_data.interrupted unless handle_exception($!) processed_exception_in_setup = true raise end throw(tag) end end end rescue Exception if processed_exception_in_setup raise else @internal_data.interrupted raise unless handle_exception($!) end ensure begin run_teardown rescue Exception raise unless handle_exception($!) end end @internal_data.test_finished result.add_run yield(FINISHED, name) yield(FINISHED_OBJECT, self) ensure # @_result = nil # For test-spec's after_all :< end end |
#setup ⇒ Object
Called before every test method runs. Can be used to set up fixture information.
You can add additional setup tasks by the following code:
class TestMyClass < Test::Unit::TestCase
def setup
...
end
setup
def my_setup1
...
end
setup do
... # setup callback1
end
setup
def my_setup2
...
end
setup do
... # setup callback2
end
def test_my_class
...
end
end
Here is a call order:
-
setup
-
my_setup1
-
setup callback1
-
my_setup2
-
setup callback2
-
test_my_class
669 670 |
# File 'lib/test/unit/testcase.rb', line 669 def setup end |
#size ⇒ Object
768 769 770 |
# File 'lib/test/unit/testcase.rb', line 768 def size 1 end |
#start_time ⇒ Object
Returns a Time at the test was started.
827 828 829 |
# File 'lib/test/unit/testcase.rb', line 827 def start_time @internal_data.start_time end |
#teardown ⇒ Object
Called after every test method runs. Can be used to tear down fixture information.
You can add additional teardown tasks by the following code:
class TestMyClass < Test::Unit::TestCase
def teardown
...
end
teardown
def my_teardown1
...
end
teardown do
... # teardown callback1
end
teardown
def my_teardown2
...
end
teardown do
... # teardown callback2
end
def test_my_class
...
end
end
Here is a call order:
-
test_my_class
-
teardown callback2
-
my_teardown2
-
teardown callback1
-
my_teardown1
-
teardown
761 762 |
# File 'lib/test/unit/testcase.rb', line 761 def teardown end |
#to_s ⇒ Object
Overridden to return #name.
814 815 816 |
# File 'lib/test/unit/testcase.rb', line 814 def to_s name end |
#valid? ⇒ Boolean
Returns the test is valid test. It is used in internal.
564 565 566 567 568 569 570 571 572 573 574 575 |
# File 'lib/test/unit/testcase.rb', line 564 def valid? # :nodoc: return false unless respond_to?(@method_name) test_method = method(@method_name) unless @internal_data.have_test_data? return false unless test_method.arity <= 0 end owner = Util::MethodOwnerFinder.find(self, @method_name) if owner.class != Module and self.class != owner return false end true end |