Class: Test::Unit::TestCase

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

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_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

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

#initialize(test_method_name) ⇒ TestCase

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



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

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

Instance Attribute Details

#method_nameObject (readonly)

Returns the value of attribute method_name.



285
286
287
# File 'lib/test/unit/testcase.rb', line 285

def method_name
  @method_name
end

Class Method Details

.added_methodsObject

:nodoc:



121
122
123
# File 'lib/test/unit/testcase.rb', line 121

def added_methods # :nodoc:
  @@added_methods[self] ||= []
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


280
281
282
# File 'lib/test/unit/testcase.rb', line 280

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

.inherited(sub_class) ⇒ Object

:nodoc:



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

def inherited(sub_class) # :nodoc:
  DESCENDANTS << sub_class
end

.method_added(name) ⇒ Object

:nodoc:



111
112
113
114
115
116
117
118
119
# File 'lib/test/unit/testcase.rb', line 111

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
  _added_methods << stringified_name
end

.shutdownObject

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.



203
204
# File 'lib/test/unit/testcase.rb', line 203

def shutdown
end

.startupObject

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.



167
168
# File 'lib/test/unit/testcase.rb', line 167

def startup
end

.suiteObject

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



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

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


249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/test/unit/testcase.rb', line 249

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

.test_orderObject

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



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

def test_order
  @@test_orders[self] || 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.



223
224
225
# File 'lib/test/unit/testcase.rb', line 223

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

Instance Method Details

#==(other) ⇒ Object

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



489
490
491
492
493
494
# File 'lib/test/unit/testcase.rb', line 489

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

#assign_test_data(label, data) ⇒ Object

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



295
296
297
# File 'lib/test/unit/testcase.rb', line 295

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

#cleanupObject

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
  def my_cleanup2
    ...
  end

  def test_my_class
    ...
  end
end

Here is a call order:

  • test_my_class

  • my_cleanup2

  • my_cleanup1

  • cleanup



413
414
# File 'lib/test/unit/testcase.rb', line 413

def cleanup
end

#data_labelObject

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



460
461
462
# File 'lib/test/unit/testcase.rb', line 460

def data_label
  @internal_data.test_data_label
end

#default_testObject



449
450
451
# File 'lib/test/unit/testcase.rb', line 449

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

#descriptionObject

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.



479
480
481
# File 'lib/test/unit/testcase.rb', line 479

def description
  self[:description] || name
end

#elapsed_timeObject

Returns elapsed time for the test was ran.



502
503
504
# File 'lib/test/unit/testcase.rb', line 502

def elapsed_time
  @internal_data.elapsed_time
end

#interrupted?Boolean

Returns whether the test is interrupted.

Returns:

  • (Boolean)


507
508
509
# File 'lib/test/unit/testcase.rb', line 507

def interrupted?
  @internal_data.interrupted?
end

#nameObject

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



466
467
468
469
470
471
472
# File 'lib/test/unit/testcase.rb', line 466

def name
  if @internal_data.have_test_data?
    "#{@method_name}[#{data_label}](#{self.class.name})"
  else
    "#{@method_name}(#{self.class.name})"
  end
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.

Returns:

  • (Boolean)


514
515
516
# File 'lib/test/unit/testcase.rb', line 514

def passed?
  @internal_data.passed?
end

#run(result) ⇒ Object

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



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/test/unit/testcase.rb', line 318

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

#setupObject

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
  def my_setup2
    ...
  end

  def test_my_class
    ...
  end
end

Here is a call order:

  • setup

  • my_setup1

  • my_setup2

  • test_my_class



378
379
# File 'lib/test/unit/testcase.rb', line 378

def setup
end

#sizeObject



453
454
455
# File 'lib/test/unit/testcase.rb', line 453

def size
  1
end

#start_timeObject

Returns a Time at the test was started.



497
498
499
# File 'lib/test/unit/testcase.rb', line 497

def start_time
  @internal_data.start_time
end

#teardownObject

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
  def my_teardown2
    ...
  end

  def test_my_class
    ...
  end
end

Here is a call order:

  • test_my_class

  • my_teardown2

  • my_teardown1

  • teardown



446
447
# File 'lib/test/unit/testcase.rb', line 446

def teardown
end

#to_sObject

Overridden to return #name.



484
485
486
# File 'lib/test/unit/testcase.rb', line 484

def to_s
  name
end

#valid?Boolean

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

Returns:

  • (Boolean)


300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/test/unit/testcase.rb', line 300

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