Class: Minitest::Test

Inherits:
Runnable show all
Extended by:
Guard
Includes:
Assertions, Guard, LifecycleHooks
Defined in:
lib/minitest/test.rb,
lib/minitest/hell.rb,
lib/minitest/parallel_each.rb

Overview

Subclass Test to create your own tests. Typically you’ll want a Test subclass per implementation class.

See Minitest::Assertions

Direct Known Subclasses

Benchmark, Spec, Unit::TestCase

Defined Under Namespace

Modules: LifecycleHooks

Constant Summary collapse

PASSTHROUGH_EXCEPTIONS =

:nodoc:

[NoMemoryError, SignalException, # :nodoc:
Interrupt, SystemExit]

Constants included from Assertions

Assertions::UNDEFINED

Instance Attribute Summary collapse

Attributes inherited from Runnable

#assertions, #failures

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Guard

jruby?, maglev?, mri?, rubinius?, windows?

Methods included from LifecycleHooks

#after_setup, #after_teardown, #before_setup, #before_teardown, #setup, #teardown

Methods included from Assertions

#assert, #assert_empty, #assert_equal, #assert_in_delta, #assert_in_epsilon, #assert_includes, #assert_instance_of, #assert_kind_of, #assert_match, #assert_nil, #assert_operator, #assert_output, #assert_predicate, #assert_raises, #assert_respond_to, #assert_same, #assert_send, #assert_silent, #assert_throws, #diff, diff, diff=, #exception_details, #flunk, #message, #mu_pp, #mu_pp_for_diff, #pass, #refute, #refute_empty, #refute_equal, #refute_in_delta, #refute_in_epsilon, #refute_includes, #refute_instance_of, #refute_kind_of, #refute_match, #refute_nil, #refute_operator, #refute_predicate, #refute_respond_to, #refute_same, #skip

Methods inherited from Runnable

#failure, inherited, #initialize, methods_matching, #name, #name=, on_signal, reset, run, runnables, with_info_handler

Constructor Details

This class inherits a constructor from Minitest::Runnable

Instance Attribute Details

#timeObject

The time it took to run this test.



88
89
90
# File 'lib/minitest/test.rb', line 88

def time
  @time
end

Class Method Details

.i_suck_and_my_tests_are_order_dependent!Object

Call this at the top of your tests when you absolutely positively need to have ordered tests. In doing so, you’re admitting that you suck and your tests are weak.



20
21
22
23
24
25
# File 'lib/minitest/test.rb', line 20

def self.i_suck_and_my_tests_are_order_dependent!
  class << self
    undef_method :test_order if method_defined? :test_order
    define_method :test_order do :alpha end
  end
end

.make_my_diffs_pretty!Object

Make diffs for this Test use #pretty_inspect so that diff in assert_equal can have more details. NOTE: this is much slower than the regular inspect but much more usable for complex objects.



33
34
35
36
37
38
39
# File 'lib/minitest/test.rb', line 33

def self.make_my_diffs_pretty!
  require "pp"

  define_method :mu_pp do |o|
    o.pretty_inspect
  end
end

.old_test_orderObject

:nodoc:



5
# File 'lib/minitest/hell.rb', line 5

alias :old_test_order :test_order

.parallelize_me!Object

Call this at the top of your tests when you want to run your tests in parallel. In doing so, you’re admitting that you rule and your tests are awesome.



46
47
48
49
50
51
52
53
# File 'lib/minitest/test.rb', line 46

def self.parallelize_me!
  require "minitest/parallel_each"

  class << self
    undef_method :test_order if method_defined? :test_order
    define_method :test_order do :parallel end
  end
end

.runnable_methodsObject

Returns all instance methods starting with “test_”. Based on #test_order, the methods are either sorted, randomized (default), or run in parallel.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/minitest/test.rb', line 60

def self.runnable_methods
  methods = methods_matching(/^test_/)

  case self.test_order
  when :parallel
    max = methods.size
    ParallelEach.new methods.sort.sort_by { rand max }
  when :random then
    max = methods.size
    methods.sort.sort_by { rand max }
  when :alpha, :sorted then
    methods.sort
  else
    raise "Unknown test_order: #{self.test_order.inspect}"
  end
end

.synchronizeObject

:nodoc:



63
64
65
66
67
68
69
# File 'lib/minitest/parallel_each.rb', line 63

def self.synchronize # :nodoc:
  if @mutex then # see parallel_each.rb
    @mutex.synchronize { yield }
  else
    yield
  end
end

.test_orderObject

Defines the order to run tests (:random by default). Override this or use a convenience method to change it for your tests.



7
8
9
# File 'lib/minitest/hell.rb', line 7

def test_order # :nodoc:
  :parallel
end

Instance Method Details

#capture_exceptionsObject

LifecycleHooks



204
205
206
207
208
209
210
211
212
213
214
# File 'lib/minitest/test.rb', line 204

def capture_exceptions # :nodoc:
  begin
    yield
  rescue *PASSTHROUGH_EXCEPTIONS
    raise
  rescue Assertion => e
    self.failures << e
  rescue Exception => e
    self.failures << UnexpectedError.new(e)
  end
end

#capture_io(&b) ⇒ Object



73
74
75
76
77
# File 'lib/minitest/parallel_each.rb', line 73

def capture_io(&b)
  Test.synchronize do
    simple_capture_io(&b)
  end
end

#capture_subprocess_io(&b) ⇒ Object



81
82
83
84
85
# File 'lib/minitest/parallel_each.rb', line 81

def capture_subprocess_io(&b)
  Test.synchronize do
    simple_capture_subprocess_io(&b)
  end
end

#error?Boolean

Did this run error?

Returns:

  • (Boolean)


219
220
221
# File 'lib/minitest/test.rb', line 219

def error?
  self.failures.any? { |f| UnexpectedError === f }
end

#locationObject

The location identifier of this test.



226
227
228
229
# File 'lib/minitest/test.rb', line 226

def location
  loc = " [#{self.failure.location}]" unless passed? or error?
  "#{self.class}##{self.name}#{loc}"
end

#marshal_dumpObject

:nodoc:



90
91
92
# File 'lib/minitest/test.rb', line 90

def marshal_dump # :nodoc:
  super << self.time
end

#marshal_load(ary) ⇒ Object

:nodoc:



94
95
96
97
# File 'lib/minitest/test.rb', line 94

def marshal_load ary # :nodoc:
  self.time = ary.pop
  super
end

#passed?Boolean

Did this run pass?

Note: skipped runs are not considered passing, but they don’t cause the process to exit non-zero.

Returns:

  • (Boolean)


237
238
239
# File 'lib/minitest/test.rb', line 237

def passed?
  not self.failure
end

#result_codeObject

Returns “.”, “F”, or “E” based on the result of the run.



244
245
246
# File 'lib/minitest/test.rb', line 244

def result_code
  self.failure and self.failure.result_code or "."
end

#runObject

Runs a single test with setup/teardown hooks.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/minitest/test.rb', line 102

def run
  with_info_handler do
    time_it do
      capture_exceptions do
        before_setup; setup; after_setup

        self.send self.name
      end

      %w{ before_teardown teardown after_teardown }.each do |hook|
        capture_exceptions do
          self.send hook
        end
      end
    end
  end

  self # per contract
end

#simple_capture_ioObject



71
# File 'lib/minitest/parallel_each.rb', line 71

alias :simple_capture_io :capture_io

#simple_capture_subprocess_ioObject



79
# File 'lib/minitest/parallel_each.rb', line 79

alias :simple_capture_subprocess_io :capture_subprocess_io

#skipped?Boolean

Was this run skipped?

Returns:

  • (Boolean)


251
252
253
# File 'lib/minitest/test.rb', line 251

def skipped?
  self.failure and Skip === self.failure
end

#time_itObject

:nodoc:



255
256
257
258
259
260
261
# File 'lib/minitest/test.rb', line 255

def time_it # :nodoc:
  t0 = Time.now

  yield
ensure
  self.time = Time.now - t0
end

#to_sObject

:nodoc:



263
264
265
266
267
268
269
# File 'lib/minitest/test.rb', line 263

def to_s # :nodoc:
  return location if passed? and not skipped?

  failures.map { |failure|
    "#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
  }.join "\n"
end

#with_info_handler(&block) ⇒ Object

:nodoc:



271
272
273
274
275
276
277
278
279
# File 'lib/minitest/test.rb', line 271

def with_info_handler &block # :nodoc:
  t0 = Time.now

  handler = lambda do
    warn "\nCurrent: %s#%s %.2fs" % [self.class, self.name, Time.now - t0]
  end

  self.class.on_signal "INFO", handler, &block
end