Class: MiniTest::Unit

Inherits:
Object show all
Defined in:
lib/minitest/benchmark.rb,
lib/minitest/unit.rb

Overview

:nodoc:

Defined Under Namespace

Modules: Deprecated, Guard, LifecycleHooks Classes: TestCase

Constant Summary collapse

VERSION =

:nodoc:

"4.1.0"
@@out =
$stdout
@@after_tests =
[]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeUnit

:nodoc:



946
947
948
949
950
951
# File 'lib/minitest/unit.rb', line 946

def initialize # :nodoc:
  @report = []
  @errors = @failures = @skips = 0
  @verbose = false
  self.last_error = nil
end

Instance Attribute Details

#assertion_countObject

:nodoc:



712
713
714
# File 'lib/minitest/unit.rb', line 712

def assertion_count
  @assertion_count
end

#errorsObject

:nodoc:



711
712
713
# File 'lib/minitest/unit.rb', line 711

def errors
  @errors
end

#failuresObject

:nodoc:



711
712
713
# File 'lib/minitest/unit.rb', line 711

def failures
  @failures
end

#helpObject

:nodoc:



714
715
716
# File 'lib/minitest/unit.rb', line 714

def help
  @help
end

#last_errorObject

:nodoc:



717
718
719
# File 'lib/minitest/unit.rb', line 717

def last_error
  @last_error
end

#optionsObject

Lazy accessor for options.



722
723
724
# File 'lib/minitest/unit.rb', line 722

def options
  @options ||= {}
end

#reportObject

:nodoc:



711
712
713
# File 'lib/minitest/unit.rb', line 711

def report
  @report
end

#skipsObject

:nodoc:



711
712
713
# File 'lib/minitest/unit.rb', line 711

def skips
  @skips
end

#start_timeObject

:nodoc:



713
714
715
# File 'lib/minitest/unit.rb', line 713

def start_time
  @start_time
end

#test_countObject

:nodoc:



712
713
714
# File 'lib/minitest/unit.rb', line 712

def test_count
  @test_count
end

#verboseObject

:nodoc:



715
716
717
# File 'lib/minitest/unit.rb', line 715

def verbose
  @verbose
end

Class Method Details

.after_tests(&block) ⇒ Object

A simple hook allowing you to run a block of code after all of the tests are done. Eg:

MiniTest::Unit.after_tests { p $debugging_info }


736
737
738
# File 'lib/minitest/unit.rb', line 736

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

.autorunObject

Registers MiniTest::Unit to run tests at process exit



743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
# File 'lib/minitest/unit.rb', line 743

def self.autorun
  at_exit {
    next if $! # don't run if there was an exception

    # the order here is important. The at_exit handler must be
    # installed before anyone else gets a chance to install their
    # own, that way we can be assured that our exit will be last
    # to run (at_exit stacks).
    exit_code = nil

    at_exit {
      @@after_tests.reverse_each(&:call)
      exit false if exit_code && exit_code != 0
    }

    exit_code = MiniTest::Unit.new.run ARGV
  } unless @@installed_at_exit
  @@installed_at_exit = true
end

.outputObject

Returns the stream to use for output.



766
767
768
# File 'lib/minitest/unit.rb', line 766

def self.output
  @@out
end

.output=(stream) ⇒ Object

Sets MiniTest::Unit to write output to stream. $stdout is the default output



774
775
776
# File 'lib/minitest/unit.rb', line 774

def self.output= stream
  @@out = stream
end

.pluginsObject

Return all plugins’ run methods (methods that start with “run_”).



798
799
800
801
802
# File 'lib/minitest/unit.rb', line 798

def self.plugins
  @@plugins ||= (["run_tests"] +
                 public_instance_methods(false).
                 grep(/^run_/).map { |s| s.to_s }).uniq
end

.runnerObject

Returns the MiniTest::Unit subclass instance that will be used to run the tests. A MiniTest::Unit instance is the default runner.



791
792
793
# File 'lib/minitest/unit.rb', line 791

def self.runner
  @@runner ||= self.new
end

.runner=(runner) ⇒ Object

Tells MiniTest::Unit to delegate to runner, an instance of a MiniTest::Unit subclass, when MiniTest::Unit#run is called.



782
783
784
# File 'lib/minitest/unit.rb', line 782

def self.runner= runner
  @@runner = runner
end

Instance Method Details

#_run(args = []) ⇒ Object

Top level driver, controls all output and filtering.



1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
# File 'lib/minitest/unit.rb', line 1006

def _run args = []
  self.options = process_args args

  puts "Run options: #{help}"

  self.class.plugins.each do |plugin|
    send plugin
    break unless report.empty?
  end

  return failures + errors if @test_count > 0 # or return nil...
rescue Interrupt
  abort 'Interrupted'
end

#_run_anything(type) ⇒ Object

Runner for a given type (eg, test vs bench).



822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
# File 'lib/minitest/unit.rb', line 822

def _run_anything type
  suites = TestCase.send "#{type}_suites"
  return if suites.empty?

  start = Time.now

  puts
  puts "# Running #{type}s:"
  puts

  @test_count, @assertion_count = 0, 0
  sync = output.respond_to? :"sync=" # stupid emacs
  old_sync, output.sync = output.sync, true if sync

  results = _run_suites suites, type

  @test_count      = results.inject(0) { |sum, (tc, _)| sum + tc }
  @assertion_count = results.inject(0) { |sum, (_, ac)| sum + ac }

  output.sync = old_sync if sync

  t = Time.now - start

  puts
  puts
  puts "Finished #{type}s in %.6fs, %.4f tests/s, %.4f assertions/s." %
    [t, test_count / t, assertion_count / t]

  report.each_with_index do |msg, i|
    puts "\n%3d) %s" % [i + 1, msg]
  end

  puts

  status
end

#_run_suite(suite, type) ⇒ Object

Run a single suite for a given type.



869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
# File 'lib/minitest/unit.rb', line 869

def _run_suite suite, type
  header = "#{type}_suite_header"
  puts send(header, suite) if respond_to? header

  filter = options[:filter] || '/./'
  filter = Regexp.new $1 if filter =~ /\/(.*)\//

  assertions = suite.send("#{type}_methods").grep(filter).map { |method|
    inst = suite.new method
    inst._assertions = 0

    print "#{suite}##{method} = " if @verbose

    @start_time = Time.now
    self.last_error = nil
    result = inst.run self
    time = Time.now - @start_time

    record suite, method, inst._assertions, time, last_error

    print "%.2f s = " % time if @verbose
    print result
    puts if @verbose

    inst._assertions
  }

  return assertions.size, assertions.inject(0) { |sum, n| sum + n }
end

#_run_suites(suites, type) ⇒ Object

Runs all the suites for a given type.



862
863
864
# File 'lib/minitest/unit.rb', line 862

def _run_suites suites, type
  suites.map { |suite| _run_suite suite, type }
end

#benchmark_suite_header(suite) ⇒ Object

:nodoc:



9
10
11
# File 'lib/minitest/benchmark.rb', line 9

def benchmark_suite_header suite # :nodoc:
  "\n#{suite}\t#{suite.bench_range.join("\t")}"
end

#location(e) ⇒ Object

:nodoc:



914
915
916
917
918
919
920
921
# File 'lib/minitest/unit.rb', line 914

def location e # :nodoc:
  last_before_assertion = ""
  e.backtrace.reverse_each do |s|
    break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
    last_before_assertion = s
  end
  last_before_assertion.sub(/:in .*$/, '')
end

#outputObject

Return the IO for output.



807
808
809
# File 'lib/minitest/unit.rb', line 807

def output
  self.class.output
end

:nodoc:



815
816
817
# File 'lib/minitest/unit.rb', line 815

def print *a # :nodoc:
  output.print(*a)
end

#process_args(args = []) ⇒ Object

:nodoc:



953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
# File 'lib/minitest/unit.rb', line 953

def process_args args = [] # :nodoc:
  options = {}
  orig_args = args.dup

  OptionParser.new do |opts|
    opts.banner  = 'minitest options:'
    opts.version = MiniTest::Unit::VERSION

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

    opts.on '-s', '--seed SEED', Integer, "Sets random seed" do |m|
      options[:seed] = m.to_i
    end

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

    opts.on '-n', '--name PATTERN', "Filter test names on pattern (e.g. /foo/)" do |a|
      options[:filter] = a
    end

    opts.parse! args
    orig_args -= args
  end

  unless options[:seed] then
    srand
    options[:seed] = srand % 0xFFFF
    orig_args << "--seed" << options[:seed].to_s
  end

  srand options[:seed]

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

  options
end

#puke(klass, meth, e) ⇒ Object

Writes status for failed test meth in klass which finished with exception e



927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
# File 'lib/minitest/unit.rb', line 927

def puke klass, meth, e
  self.last_error = e
  e = case e
      when MiniTest::Skip then
        @skips += 1
        return "S" unless @verbose
        "Skipped:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
      when MiniTest::Assertion then
        @failures += 1
        "Failure:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
      else
        @errors += 1
        bt = MiniTest::filter_backtrace(e.backtrace).join "\n    "
        "Error:\n#{meth}(#{klass}):\n#{e.class}: #{e.message}\n    #{bt}\n"
      end
  @report << e
  e[0, 1]
end

#puts(*a) ⇒ Object

:nodoc:



811
812
813
# File 'lib/minitest/unit.rb', line 811

def puts *a  # :nodoc:
  output.puts(*a)
end

#record(suite, method, assertions, time, error) ⇒ Object

Record the result of a single run. Makes it very easy to gather information. Eg:

class StatisticsRecorder < MiniTest::Unit
  def record suite, method, assertions, time, error
    # ... record the results somewhere ...
  end
end

MiniTest::Unit.runner = StatisticsRecorder.new


911
912
# File 'lib/minitest/unit.rb', line 911

def record suite, method, assertions, time, error
end

#run(args = []) ⇒ Object

Begins the full test run. Delegates to runner‘s #_run method.



999
1000
1001
# File 'lib/minitest/unit.rb', line 999

def run args = []
  self.class.runner._run(args)
end

#run_benchmarksObject

:nodoc:



5
6
7
# File 'lib/minitest/benchmark.rb', line 5

def run_benchmarks # :nodoc:
  _run_anything :benchmark
end

#run_testsObject

Runs test suites matching filter.



1024
1025
1026
# File 'lib/minitest/unit.rb', line 1024

def run_tests
  _run_anything :test
end

#status(io = self.output) ⇒ Object

Writes status to io



1031
1032
1033
1034
# File 'lib/minitest/unit.rb', line 1031

def status io = self.output
  format = "%d tests, %d assertions, %d failures, %d errors, %d skips"
  io.puts format % [test_count, assertion_count, failures, errors, skips]
end