Module: Minitest

Defined in:
lib/minitest.rb,
lib/minitest/mock.rb,
lib/minitest/test.rb,
lib/minitest/unit.rb,
lib/minitest/compress.rb,
lib/minitest/parallel.rb,
lib/minitest/benchmark.rb,
lib/minitest/benchmark.rb,
lib/minitest/test_task.rb,
lib/minitest/assertions.rb,
lib/minitest/pride_plugin.rb

Overview

:nodoc:

Defined Under Namespace

Modules: Assertions, Compress, Expectations, Guard, Parallel, Reportable Classes: AbstractReporter, Assertion, BacktraceFilter, BenchSpec, Benchmark, CompositeReporter, Mock, PrideIO, PrideLOL, ProgressReporter, Reporter, Result, Runnable, Skip, Spec, StatisticsReporter, SummaryReporter, Test, TestTask, UnexpectedError, Unit

Constant Summary collapse

VERSION =

:nodoc:

"5.22.2"
@@after_run =
[]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.__run(reporter, options) ⇒ Object

Internal run method. Responsible for telling all Runnable sub-classes to run.



197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/minitest.rb', line 197

def self.__run reporter, options
  suites = Runnable.runnables.shuffle
  parallel, serial = suites.partition { |s| s.test_order == :parallel }

  # If we run the parallel tests before the serial tests, the parallel tests
  # could run in parallel with the serial tests. This would be bad because
  # the serial tests won't lock around Reporter#record. Run the serial tests
  # first, so that after they complete, the parallel tests will lock when
  # recording results.
  serial.map { |suite| suite.run reporter, options } +
    parallel.map { |suite| suite.run reporter, options }
end

.after_run(&block) ⇒ Object

A simple hook allowing you to run a block of code after everything is done running. Eg:

Minitest.after_run { p $debugging_info }


97
98
99
# File 'lib/minitest.rb', line 97

def self.after_run &block
  @@after_run << block
end

.autorunObject

Registers Minitest to run at process exit



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/minitest.rb', line 69

def self.autorun
  if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
    Warning[:deprecated] = true
  end

  at_exit {
    next if $! and not ($!.kind_of? SystemExit and $!.success?)

    exit_code = nil

    pid = Process.pid
    at_exit {
      next if !Minitest.allow_fork && Process.pid != pid
      @@after_run.reverse_each(&:call)
      exit exit_code || false
    }

    exit_code = Minitest.run ARGV
  } unless @@installed_at_exit
  @@installed_at_exit = true
end

.cattr_accessor(name) ⇒ Object

:nodoc:



18
19
20
# File 'lib/minitest.rb', line 18

def self.cattr_accessor name # :nodoc:
  (class << self; self; end).attr_accessor name
end

.clock_timeObject

:nodoc:



1146
1147
1148
# File 'lib/minitest.rb', line 1146

def self.clock_time
  Process.clock_gettime Process::CLOCK_MONOTONIC
end

.empty_run!(options) ⇒ Object

:nodoc:



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/minitest.rb', line 177

def self.empty_run! options # :nodoc:
  filter = options[:filter]
  return true unless filter # no filter, but nothing ran == success

  warn "Nothing ran for filter: %s" % [filter]

  require "did_you_mean" # soft dependency, punt if it doesn't load

  ms = Runnable.runnables.flat_map(&:runnable_methods)
  cs = DidYouMean::SpellChecker.new(dictionary: ms).correct filter

  warn DidYouMean::Formatter.message_for cs unless cs.empty?
rescue LoadError
  # do nothing
end

.filter_backtrace(bt) ⇒ Object

:nodoc:



292
293
294
295
296
# File 'lib/minitest.rb', line 292

def self.filter_backtrace bt # :nodoc:
  result = backtrace_filter.filter bt
  result = bt.dup if result.empty?
  result
end

.init_plugins(options) ⇒ Object

:nodoc:



101
102
103
104
105
106
# File 'lib/minitest.rb', line 101

def self.init_plugins options # :nodoc:
  self.extensions.each do |name|
    msg = "plugin_#{name}_init"
    send msg, options if self.respond_to? msg
  end
end

.load_pluginsObject

:nodoc:



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/minitest.rb', line 108

def self.load_plugins # :nodoc:
  return unless self.extensions.empty?

  seen = {}

  require "rubygems" unless defined? Gem

  Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
    name = File.basename plugin_path, "_plugin.rb"

    next if seen[name]
    seen[name] = true

    require plugin_path
    self.extensions << name
  end
end

.plugin_pride_init(options) ⇒ Object

:nodoc:



10
11
12
13
14
15
16
17
18
19
# File 'lib/minitest/pride_plugin.rb', line 10

def self.plugin_pride_init options # :nodoc:
  if PrideIO.pride? then
    klass = ENV["TERM"] =~ /^xterm|-256color$/ ? PrideLOL : PrideIO
    io    = klass.new options[:io]

    self.reporter.reporters.grep(Minitest::Reporter).each do |rep|
      rep.io = io if rep.io.tty?
    end
  end
end

.plugin_pride_options(opts, _options) ⇒ Object

:nodoc:



4
5
6
7
8
# File 'lib/minitest/pride_plugin.rb', line 4

def self.plugin_pride_options opts, _options # :nodoc:
  opts.on "-p", "--pride", "Pride. Show your testing pride!" do
    PrideIO.pride!
  end
end

.process_args(args = []) ⇒ Object

:nodoc:



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/minitest.rb', line 210

def self.process_args args = [] # :nodoc:
  options = {
             :io => $stdout,
            }
  orig_args = args.dup

  OptionParser.new do |opts|
    opts.banner  = "minitest options:"
    opts.version = Minitest::VERSION

    opts.on "-h", "--help", "Display this help." do
      puts opts
      exit
    end

    opts.on "--no-plugins", "Bypass minitest plugin auto-loading (or set $MT_NO_PLUGINS)."

    desc = "Sets random seed. Also via env. Eg: SEED=n rake"
    opts.on "-s", "--seed SEED", Integer, desc do |m|
      options[:seed] = m.to_i
    end

    opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
      options[:verbose] = true
    end

    opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
      options[:quiet] = true
    end

    opts.on "--show-skips", "Show skipped at the end of run." do
      options[:show_skips] = true
    end

    opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
      options[:filter] = a
    end

    opts.on "-e", "--exclude PATTERN", "Exclude /regexp/ or string from run." do |a|
      options[:exclude] = a
    end

    opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
      options[:skip] = s.chars.to_a
    end

    unless extensions.empty?
      opts.separator ""
      opts.separator "Known extensions: #{extensions.join(", ")}"

      extensions.each do |meth|
        msg = "plugin_#{meth}_options"
        send msg, opts, options if self.respond_to?(msg)
      end
    end

    begin
      opts.parse! args
    rescue OptionParser::InvalidOption => e
      puts
      puts e
      puts
      puts opts
      exit 1
    end

    orig_args -= args
  end

  unless options[:seed] then
    srand
    options[:seed] = (ENV["SEED"] || srand).to_i % 0xFFFF
    orig_args << "--seed" << options[:seed].to_s
  end

  options[:args] = orig_args.map { |s|
    s =~ /[\s|&<>$()]/ ? s.inspect : s
  }.join " "

  options
end

.run(args = []) ⇒ Object

This is the top-level run method. Everything starts from here. It tells each Runnable sub-class to run, and each of those are responsible for doing whatever they do.

The overall structure of a run looks like this:

Minitest.autorun
  Minitest.run(args)
    Minitest.__run(reporter, options)
      Runnable.runnables.each
        runnable_klass.run(reporter, options)
          self.runnable_methods.each
            self.run_one_method(self, runnable_method, reporter)
              Minitest.run_one_method(klass, runnable_method)
                klass.new(runnable_method).run


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/minitest.rb', line 143

def self.run args = []
  self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]

  options = process_args args

  Minitest.seed = options[:seed]
  srand Minitest.seed

  reporter = CompositeReporter.new
  reporter << SummaryReporter.new(options[:io], options)
  reporter << ProgressReporter.new(options[:io], options) unless options[:quiet]

  self.reporter = reporter # this makes it available to plugins
  self.init_plugins options
  self.reporter = nil # runnables shouldn't depend on the reporter, ever

  self.parallel_executor.start if parallel_executor.respond_to?(:start)
  reporter.start
  begin
    __run reporter, options
  rescue Interrupt
    warn "Interrupted. Exiting..."
  end
  self.parallel_executor.shutdown

  # might have been removed/replaced during init_plugins:
  summary = reporter.reporters.grep(SummaryReporter).first
  return empty_run! options if summary && summary.count == 0

  reporter.report

  reporter.passed?
end

.run_one_method(klass, method_name) ⇒ Object

:nodoc:



1137
1138
1139
1140
1141
# File 'lib/minitest.rb', line 1137

def self.run_one_method klass, method_name # :nodoc:
  result = klass.new(method_name).run
  raise "#{klass}#run _must_ return a Result" unless Result === result
  result
end

Instance Method Details

#backtrace_filterObject

Filter object for backtraces.



43
# File 'lib/minitest.rb', line 43

cattr_accessor :backtrace_filter

#extensionsObject

Names of known extension plugins.



55
# File 'lib/minitest.rb', line 55

cattr_accessor :extensions

#info_signalObject

The signal to use for dumping information to STDERR. Defaults to “INFO”.



60
# File 'lib/minitest.rb', line 60

cattr_accessor :info_signal

#parallel_executorObject

Parallel test executor



33
# File 'lib/minitest.rb', line 33

cattr_accessor :parallel_executor

#reporterObject

Reporter object to be used for all runs.

NOTE: This accessor is only available during setup, not during runs.



50
# File 'lib/minitest.rb', line 50

cattr_accessor :reporter

#seedObject

The random seed used for this run. This is used to srand at the start of the run and between each Runnable.run.

Set via Minitest.run after processing args.



28
# File 'lib/minitest.rb', line 28

cattr_accessor :seed