class Test::Unit::TestCase
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
Attributes
Public Class Methods
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 374 def description(value, target=nil) targets = [target].compact attribute(:description, value, {}, *targets) end
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
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 475 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
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 588 def initialize(test_method_name) @method_name = test_method_name @internal_data = InternalData.new end
Creates a new instance of the fixture for running the test represented by test_method_name.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 149 def parallel_safe? true end
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.
@example Indicates that test_parallel_unsafe is parallel unsafe
class TestMyClass < Test::Unit::TestCase class << self def parallel_safe? false end end def test_parallel_unsafe # ... end end
@since 3.6.3
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 413 def ractor(options={}) attribute(:ractor, true, options) end
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`.
@param options [Hash] See {Attribute::ClassMethods#attribute}
for details.
@return [void]
@example Declares that test_do_something_with_ractor uses Ractor
ractor def test_do_something_with_ractor Ractor.new do # ... end end
@example Declares that test_do_something_with_ractor uses Ractor in one line
ractor def test_do_something_with_ractor Ractor.new do # ... end end
@since 3.4.6
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 284 def shutdown end
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.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 246 def startup end
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.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 455 def sub_test_case(name, &block) sub_test_case = sub_test_case_class(name) sub_test_case.class_eval(&block) sub_test_case end
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:
-
Testcase created by {sub_test_case} is backed by an anonymous class, but it is assigned to an auto generated constant. So it can be referred to by name (e.g. for ‘Marshal.dump` and across process use). -
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”.
@param name [String] The name of newly created sub test case. @yield
The block is evaluated under the newly created sub test case class context.
@return [Test::Unit::TestCase] Created sub test case class.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 205 def suite suite_creator = TestSuiteCreator.new(self) suite_creator.create end
Rolls up all of the test* methods in the fixture into one suite, creating a new instance of the fixture for each method.
Source
# File bundled-src/test-unit-3.7.5/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 message = "wrong number of arguments (#{n_arguments} for 1)" raise ArgumentError, message 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
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
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 470 def test_defined?(query) locations = find_locations(query) not locations.empty? end
Checks whether a test that is matched the query is defined.
@option query [String] :path (nil)
the path where a test is defined in.
@option query [Numeric] :line (nil)
the line number where a test is defined at.
@option query [String] :method_name (nil)
the method name for a test.
Source
# File bundled-src/test-unit-3.7.5/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
Returns the current test order. This returns ‘:alphabetic` by default.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 311 def test_order=(order) @@test_orders[self] = order end
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.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 514 def worker_id @worker_id || 0 end
Returns a current worker ID for the test case. This return depends on how tests are run:
* Sequential: always returns `0` * Parallel: returns a one-based to the number of workers.
@return [Integer]
@since 3.7.4
Private Class Methods
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 534 def add_method_location(location) @@method_location_mutex.synchronize do method_locations << location end end
@private
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 529 def method_locations @@method_locations[self] ||= [] end
@private
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 565 def sub_test_case_class(name) parent_test_case = self sub_test_case = Class.new(self) do singleton_class = class << self; self; end singleton_class.__send__(:define_method, :name) do [parent_test_case.name, name].compact.join("::") end end # Give the anonymous class a unique, Base64 encoded constant # name. So it becomes a named class that `Marshal` can # safely dump even across processes. # # We can't use "\n", "=" and "/" in base64 as class name. encoded_name = [sub_test_case.name].pack("m").delete("\n=/") const_set(:"TEST_#{encoded_name}", sub_test_case) sub_test_case end
@private
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 541 def target_method_locations(path) @@method_location_mutex.synchronize do if path.nil? self_location = method_locations.first path = self_location[:path] if self_location end return [] if path.nil? target_locations = [] @@method_locations.each do |test_case, locations| locations.each do |location| absolete_path = File.expand_path(path) location_path = location[:path] location_basename = File.basename(location_path) if location_path == absolete_path or location_basename == path target_locations << location.merge(:test_case => test_case) end end end target_locations end end
@private
Public Instance Methods
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 875 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
It’s handy to be able to compare TestCase instances.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 929 def add_pass current_result.add_pass end
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.
@return [void]
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 762 def cleanup end
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
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 837 def data @internal_data.test_data end
Returns test data for the test. If the test isn’t associated with any test data, it returns ‘nil`.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 831 def data_label @internal_data.test_data_label end
Returns a label of test data for the test. If the test isn’t associated with any test data, it returns ‘nil`.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 810 def default_test flunk("No tests were specified") end
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 865 def description self[:description] || name end
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.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 888 def elapsed_time @internal_data.elapsed_time end
Returns elapsed time for the test was ran.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 893 def interrupted? @internal_data.interrupted? end
Returns whether the test is interrupted.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 852 def local_name if @internal_data.have_test_data? "#{@method_name}[#{data_label}]" else @method_name.to_s end end
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.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 933 def marshal_dump { method_name: @method_name, internal_data: @internal_data, } end
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 940 def marshal_load(data) @method_name = data[:method_name] @internal_data = data[:internal_data] end
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 843 def name "#{local_name}(#{self.class.name})" end
Returns a human-readable name for the specific test that this instance of TestCase represents.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 900 def passed? @internal_data.passed? end
Returns whether this individual test passed or not. Primarily for use in teardown so that artifacts can be left behind if the test fails.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 911 def problem_occurred @internal_data.problem_occurred end
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.
@return [void]
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 615 def run(worker_context) begin unless worker_context.is_a?(WorkerContext) result = worker_context worker_context = WorkerContext.new(nil, nil, result) end result = worker_context.result @_result = result instance_variables_before = instance_variables @internal_data.run_context = worker_context.run_context @internal_data.worker_id = worker_context.id @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 :< (instance_variables - instance_variables_before).each do |name| remove_instance_variable(name) end end end
Runs the individual test method represented by this instance of the fixture, collecting statistics, failures and errors in result.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 916 def runner_class @internal_data.run_context.runner_class end
Returns test suite runner class for easy to test.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 715 def setup end
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
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 814 def size 1 end
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 883 def start_time @internal_data.start_time end
Returns a Time at the test was started.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 807 def teardown end
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
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 870 def to_s name end
Overridden to return name.
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 824 def worker_id @internal_data.worker_id || 0 end
Returns a current worker ID for the test. See {TestCase.worker_id} for details.
@return [Integer]
@since 3.7.4
Private Instance Methods
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 985 def add_assertion current_result.add_assertion end
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 946 def current_result @_result end
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 973 def handle_exception(exception) self.class.exception_handlers.each do |handler| if handler.respond_to?(:call) handled = handler.call(self, exception) else handled = __send__(handler, exception) end return true if handled end false end
Source
# File bundled-src/test-unit-3.7.5/lib/test/unit/testcase.rb, line 950 def run_test signature = "#{self.class}\##{@method_name}" redefined_info = self[:redefined] if redefined_info notify("<#{signature}> was redefined", :backtrace => redefined_info[:backtrace]) end if self[:ractor] and not defined?(::Ractor) omit("<#{signature}> requires Ractor") end if @internal_data.have_test_data? test_method = method(@method_name) arity = test_method.arity if arity.zero? __send__(@method_name) else __send__(@method_name, @internal_data.test_data) end else __send__(@method_name) end end