Class: Test::Unit::TestCase — test-unit - test-unit

Class: Test::Unit::TestCase

Inherits:
Object
  • Object
show all
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

Constant Summary

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_methods =
{}
@@test_orders =
{}

Constants included from Util::BacktraceFilter

Util::BacktraceFilter::TESTUNIT_FILE_SEPARATORS, Util::BacktraceFilter::TESTUNIT_PREFIX, Util::BacktraceFilter::TESTUNIT_RB_FILE

Constants included from Assertions

Assertions::UncaughtThrow

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)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Util::Output

#capture_output

Methods included from Util::BacktraceFilter

filter_backtrace

Methods included from Assertions

#assert, #assert_alias_method, #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_match, #assert_not_nil, #assert_not_predicate, #assert_not_respond_to, #assert_not_same, #assert_not_send, #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_raises, #assert_respond_to, #assert_same, #assert_send, #assert_throw, #assert_throws, #assert_true, #build_message, #flunk, use_pp=

Methods included from Data

included

Methods included from Priority

available_values, default, default=, disable, enable, enabled?, included, #priority_setup, #priority_teardown

Methods included from TestCaseNotificationSupport

included, #notify

Methods included from TestCaseOmissionSupport

included, #omit, #omit_if, #omit_unless

Methods included from TestCasePendingSupport

included, #pend

Methods included from FailureHandler

#add_failure, included

Methods included from ErrorHandler

included

Methods included from ExceptionHandler

exception_handlers, included

Methods included from Fixture

included

Methods included from Attribute

#[], #attributes, included

Constructor Details

- (TestCase) initialize(test_method_name)

Creates a new instance of the fixture for running the test represented by test_method_name.



392
393
394
395
# File 'lib/test/unit/testcase.rb', line 392

def initialize(test_method_name)
  @method_name = test_method_name
  @internal_data = InternalData.new
end

Instance Attribute Details

- (Object) method_name (readonly)

Returns the value of attribute method_name



388
389
390
# File 'lib/test/unit/testcase.rb', line 388

def method_name
  @method_name
end

Class Method Details

+ (Object) added_methods

:nodoc:



129
130
131
# File 'lib/test/unit/testcase.rb', line 129

def added_methods # :nodoc:
  @@added_methods[self] ||= []
end

+ (Object) description(value, target = nil)

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


291
292
293
# File 'lib/test/unit/testcase.rb', line 291

def description(value, target=nil)
  attribute(:description, value, {}, target || [])
end

+ (Object) inherited(sub_class)

:nodoc:



106
107
108
109
# File 'lib/test/unit/testcase.rb', line 106

def inherited(sub_class) # :nodoc:
  require "test/unit"
  DESCENDANTS << sub_class
end

+ (Object) method_added(name)

:nodoc:



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/test/unit/testcase.rb', line 112

def method_added(name) # :nodoc:
  super
  _added_methods = added_methods
  stringified_name = name.to_s
  if _added_methods.include?(stringified_name)
    attribute(:redefined, {:backtrace => caller}, {}, stringified_name)
  end
  path, line, = caller[0].split(/:(\d+)/,2)
  line = line.to_i if line
  method_locations << {
    :method_name => stringified_name,
    :path => path,
    :line => line,
  }
  _added_methods << stringified_name
end

+ (Object) shutdown

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.



211
212
# File 'lib/test/unit/testcase.rb', line 211

def shutdown
end

+ (Object) startup

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.



175
176
# File 'lib/test/unit/testcase.rb', line 175

def startup
end

+ (Test::Unit::TestCase) sub_test_case(name) { ... }

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::UnitTestCase
  class TestChild < self
    def test_in_child
    end
  end
end

Syntax sugar:

class TestParent < Test::UnitTestCase
  sub_test_case("TestChild") do
    def test_in_child
    end
  end
end

The diffrence 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".

Parameters:

  • name (String)

    The name of newly created sub test case.

Yields:

  • The block is evaludated under the newly created sub test case class context.

Returns:



330
331
332
333
334
335
336
337
338
339
# File 'lib/test/unit/testcase.rb', line 330

def sub_test_case(name, &block)
  sub_test_case = Class.new(self) do
    singleton_class = class << self; self; end
    singleton_class.send(:define_method, :name) do
      name
    end
  end
  sub_test_case.class_eval(&block)
  sub_test_case
end

+ (Object) suite

Rolls up all of the test* methods in the fixture into one suite, creating a new instance of the fixture for each method.



136
137
138
139
# File 'lib/test/unit/testcase.rb', line 136

def suite
  suite_creator = TestSuiteCreator.new(self)
  suite_creator.create
end

+ (Object) test(*test_description_or_targets, &block)

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


257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/test/unit/testcase.rb', line 257

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}"
    define_method(method_name, &block)
    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
  else
    targets = test_description_or_targets
    attribute(:test, true, {}, *targets)
  end
end

+ (Boolean) test_defined?(query)

Checkes whether a test that is mathched the query is defined.

Parameters:

  • query (Hash)

    a customizable set of options

Options Hash (query):

  • :path (String) — default: nil

    the path where a test is defined in.

  • :line (Numeric) — default: nil

    the line number where a test is defined at.

  • :method_name (String) — default: nil

    the method name for a test.

Returns:

  • (Boolean)


350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/test/unit/testcase.rb', line 350

def test_defined?(query)
  query_path = query[:path]
  query_line = query[:line]
  query_method_name = query[:method_name]

  available_locations = method_locations
  if query_path
    available_locations = available_locations.find_all do |location|
      location[:path].end_with?(query_path)
    end
  end
  if query_line
    available_location = available_locations.reverse.find do |location|
      query_line >= location[:line]
    end
    return false if available_location.nil?
    available_locations = [available_location]
  end
  if query_method_name
    available_location = available_locations.find do |location|
      query_method_name == location[:method_name]
    end
    return false if available_location.nil?
    available_locations = [available_location]
  end

  not available_locations.empty?
end

+ (Object) test_order

Returns the current test order. This returns :alphabetic by default.



218
219
220
# File 'lib/test/unit/testcase.rb', line 218

def test_order
  @@test_orders[self] || AVAILABLE_ORDERS.first
end

+ (Object) test_order=(order)

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.



231
232
233
# File 'lib/test/unit/testcase.rb', line 231

def test_order=(order)
  @@test_orders[self] = order
end

Instance Method Details

- (Object) ==(other)

It's handy to be able to compare TestCase instances.



622
623
624
625
626
627
# File 'lib/test/unit/testcase.rb', line 622

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

- (void) add_pass

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.



671
672
673
# File 'lib/test/unit/testcase.rb', line 671

def add_pass
  current_result.add_pass
end

- (Object) assign_test_data(label, data)

Assigns test data to the test. It is used in internal.



398
399
400
# File 'lib/test/unit/testcase.rb', line 398

def assign_test_data(label, data) # :nodoc:
  @internal_data.assign_test_data(label, data)
end

- (Object) cleanup

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



536
537
# File 'lib/test/unit/testcase.rb', line 536

def cleanup
end

- (Object) data_label

Returns a label of test data for the test. If the test isn't associated with any test data, it returns nil.



593
594
595
# File 'lib/test/unit/testcase.rb', line 593

def data_label
  @internal_data.test_data_label
end

- (Object) default_test



582
583
584
# File 'lib/test/unit/testcase.rb', line 582

def default_test
  flunk("No tests were specified")
end

- (Object) description

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.



612
613
614
# File 'lib/test/unit/testcase.rb', line 612

def description
  self[:description] || name
end

- (Object) elapsed_time

Returns elapsed time for the test was ran.



635
636
637
# File 'lib/test/unit/testcase.rb', line 635

def elapsed_time
  @internal_data.elapsed_time
end

- (Boolean) interrupted?

Returns whether the test is interrupted.

Returns:

  • (Boolean)


640
641
642
# File 'lib/test/unit/testcase.rb', line 640

def interrupted?
  @internal_data.interrupted?
end

- (Object) name

Returns a human-readable name for the specific test that this instance of TestCase represents.



599
600
601
602
603
604
605
# File 'lib/test/unit/testcase.rb', line 599

def name
  if @internal_data.have_test_data?
    "#{@method_name}[#{data_label}](#{self.class.name})"
  else
    "#{@method_name}(#{self.class.name})"
  end
end

- (Boolean) passed?

Returns whether this individual test passed or not. Primarily for use in teardown so that artifacts can be left behind if the test fails.

Returns:

  • (Boolean)


647
648
649
# File 'lib/test/unit/testcase.rb', line 647

def passed?
  @internal_data.passed?
end

- (void) problem_occurred

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.



658
659
660
# File 'lib/test/unit/testcase.rb', line 658

def problem_occurred
  @internal_data.problem_occurred
end

- (Object) run(result)

Runs the individual test method represented by this instance of the fixture, collecting statistics, failures and errors in result.



421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
# File 'lib/test/unit/testcase.rb', line 421

def run(result)
  begin
    @_result = result
    @internal_data.test_started
    yield(STARTED, name)
    yield(STARTED_OBJECT, self)
    begin
      run_setup
      run_test
      run_cleanup
      add_pass
    rescue Exception
      @internal_data.interrupted
      raise unless handle_exception($!)
    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

- (Object) setup

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



491
492
# File 'lib/test/unit/testcase.rb', line 491

def setup
end

- (Object) size



586
587
588
# File 'lib/test/unit/testcase.rb', line 586

def size
  1
end

- (Object) start_time

Returns a Time at the test was started.



630
631
632
# File 'lib/test/unit/testcase.rb', line 630

def start_time
  @internal_data.start_time
end

- (Object) teardown

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



579
580
# File 'lib/test/unit/testcase.rb', line 579

def teardown
end

- (Object) to_s

Overridden to return #name.



617
618
619
# File 'lib/test/unit/testcase.rb', line 617

def to_s
  name
end

- (Boolean) valid?

Returns the test is valid test. It is used in internal.

Returns:

  • (Boolean)


403
404
405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/test/unit/testcase.rb', line 403

def valid? # :nodoc:
  return false unless respond_to?(@method_name)
  test_method = method(@method_name)
  if @internal_data.have_test_data?
    return false unless test_method.arity == 1
  else
    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