diff --git a/README.txt b/README.txt index 2451a2af..7b1e6e68 100644 --- a/README.txt +++ b/README.txt @@ -174,6 +174,58 @@ Output is tab-delimited to make it easy to paste into a spreadsheet. end end +=== Customizable Test Runner Types: + +MiniTest::Unit.runner=(runner) provides an easy way of creating custom +test runners for specialized needs. Justin Weiss provides the +following real-world example to create an alternative to regular +fixture loading: + + class MiniTestWithHooks::Unit < MiniTest::Unit + def before_suites + end + + def after_suites + end + + def _run_suites(suites, type) + begin + before_suites + super(suites, type) + ensure + after_suites + end + end + + def _run_suite(suite, type) + begin + suite.before_suite + super(suite, type) + ensure + suite.after_suite + end + end + end + + module MiniTestWithTransactions + class Unit < MiniTestWithHooks::Unit + include TestSetupHelper + + def before_suites + super + setup_nested_transactions + # load any data we want available for all tests + end + + def after_suites + teardown_nested_transactions + super + end + end + end + + MiniTest::Unit.runner = MiniTestWithTransactions::Unit.new + == REQUIREMENTS: * Ruby 1.8, maybe even 1.6 or lower. No magic is involved. diff --git a/lib/minitest/unit.rb b/lib/minitest/unit.rb index b4220bd8..06176ed3 100644 --- a/lib/minitest/unit.rb +++ b/lib/minitest/unit.rb @@ -586,6 +586,23 @@ def self.output= stream @@out = stream end + ## + # Tells MiniTest::Unit to delegate to +runner+, an instance of a + # MiniTest::Unit subclass, when MiniTest::Unit#run is called. + + def self.runner= runner + @@runner = runner + end + + ## + # Returns the MiniTest::Unit subclass instance that will be used + # to run the tests. A MiniTest::Unit instance is the default + # runner. + + def self.runner + @@runner ||= self.new + end + ## # Return all plugins' run methods (methods that start with "run_"). @@ -755,9 +772,16 @@ def process_args args = [] end ## - # Top level driver, controls all output and filtering. - + # Begins the full test run. Delegates to +runner+'s #_run method. + def run args = [] + self.class.runner._run(args) + end + + ## + # Top level driver, controls all output and filtering. + + def _run args = [] self.options = process_args args puts "Run options: #{help}" diff --git a/test/test_minitest_spec.rb b/test/test_minitest_spec.rb index c3e4f462..c95a4d4c 100755 --- a/test/test_minitest_spec.rb +++ b/test/test_minitest_spec.rb @@ -197,6 +197,11 @@ end class TestMeta < MiniTest::Unit::TestCase + def test_setup + srand 42 + MiniTest::Unit::TestCase.reset + end + def util_structure x = y = z = nil before_list = [] @@ -245,9 +250,9 @@ def test_structure def test_setup_teardown_behavior x, y, z, before_list, after_list = util_structure - capture_io do - z.new(nil).run(MiniTest::Unit.new) - end + tc = z.new(nil) + tc.setup + tc.teardown assert_equal [1, 2, 3], before_list assert_equal [3, 2, 1], after_list diff --git a/test/test_minitest_unit.rb b/test/test_minitest_unit.rb index 2e5fe42f..729e8297 100755 --- a/test/test_minitest_unit.rb +++ b/test/test_minitest_unit.rb @@ -45,6 +45,7 @@ def setup def teardown MiniTest::Unit.output = $stdout + MiniTest::Unit.runner = nil Object.send :remove_const, :ATestCase if defined? ATestCase end @@ -248,7 +249,7 @@ def teardown assert_report expected end - def test_run_failing # TODO: add error test + def test_run_failing tc = Class.new(MiniTest::Unit::TestCase) do def test_something assert true @@ -354,6 +355,57 @@ def test_skip assert_report expected end + def test_default_runner_is_minitest_unit + assert_instance_of MiniTest::Unit, MiniTest::Unit.runner + end + + def test_run_with_other_runner + + runner = Class.new(MiniTest::Unit) do + # Run once before each suite + def _run_suite(suite, type) + begin + suite.before_suite + super(suite, type) + end + end + end + + tc = Class.new(MiniTest::Unit::TestCase) do + + def self.before_suite + MiniTest::Unit.output.puts "Running #{self.name} tests" + @@foo = 1 + end + + def test_something + assert_equal 1, @@foo + end + + def test_something_else + assert_equal 1, @@foo + end + end + + Object.const_set(:ATestCase, tc) + MiniTest::Unit.runner = runner.new + @tu.run %w[--seed 42] + + # We should only see 'running ATestCase tests' once + expected = "Run options: --seed 42 + +# Running tests: + +Running ATestCase tests +.. + +Finished tests in 0.00 + +2 tests, 2 assertions, 0 failures, 0 errors, 0 skips +" + assert_report expected + end + def util_expand_bt bt if RUBY_VERSION =~ /^1\.9/ then bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f }