Skip to content

Commit

Permalink
+ MiniTest::Unit.runner=(runner) provides an easy way of creating cus…
Browse files Browse the repository at this point in the history
…tom test runners for specialized needs. (justinweiss)

[git-p4: depot-paths = "//src/minitest/dev/": change = 6247]
  • Loading branch information
zenspider committed Apr 6, 2011
1 parent d4a6aed commit 6023c87
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 6 deletions.
52 changes: 52 additions & 0 deletions README.txt
Expand Up @@ -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.
Expand Down
28 changes: 26 additions & 2 deletions lib/minitest/unit.rb
Expand Up @@ -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_").

Expand Down Expand Up @@ -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}"
Expand Down
11 changes: 8 additions & 3 deletions test/test_minitest_spec.rb
Expand Up @@ -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 = []
Expand Down Expand Up @@ -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
Expand Down
54 changes: 53 additions & 1 deletion test/test_minitest_unit.rb
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 }
Expand Down

0 comments on commit 6023c87

Please sign in to comment.