Hi, I stop to object that Test::Unit is replaced with miniunit. Because nobody objects it except me. It will mean that my opinion doesn't make sense. If Matz says 'go', Test::Unit will be replaced with miniunit. I'll write my opinions in this mail below. I'm happy if my opinions are considered a bit in the future. It's OK for me if they aren't considered. In <6F321A58-07AD-4CD1-90A1-D555991A05AD / zenspider.com> "[ruby-core:17389] Re: Release Plan: Ruby 1.9.0-2" on Tue, 24 Jun 2008 10:21:45 +0900, Ryan Davis <ryand-ruby / zenspider.com> wrote: > > * miniunit isn't extensible. > > false. it is ruby. it is just as extendable as test/unit, if not more, > since it is cleaner. It seems that test/unit isn't easy to extend. So miniunit isn't easy to extend. An example is below. > > === miniunit isn't extensible > > > > Unfortunately Test::Unit doesn't keep improving itself for a > > few years. But there are many improvements in the > > world. e.g.: RSpec provides BDD style syntax, multiple > > setup/teardown (before/after) mechanism, new test (example) > > status (pending) and so on. RSpec and Mocha provides a mock > > system. > > > > Some advanced users (like ActiveSupport, Mocha and so on) > > extend Test::Unit by overriding existing methods and/or with > > Test::Unit's internal API because Test::Unit doesn't provide > > extensible interface. It causes ugly hacks. > > miniunit is compatible with ActiveSupport already. Chad Fowler did two > 1-line changes to make miniunit work with flexmock. I'm sure mocha > will take a change or two, but it won't be much. > > The ugly hacks are required for test/unit, not for miniunit. Making > miniunit work with these hacks has been ugly and painful, but it is > something we can address with the library authors and clean up over > time. e.g. active_support/testing/setup_and_teardown.rb: For test/unit: def run_with_callbacks_and_testunit(result) #:nodoc: return if @method_name.to_s == "default_test" yield(Test::Unit::TestCase::STARTED, name) @_result = result begin run_callbacks :setup setup __send__(@method_name) rescue Test::Unit::AssertionFailedError => e add_failure(e.message, e.backtrace) rescue *PASSTHROUGH_EXCEPTIONS raise rescue Exception add_error($!) ensure begin teardown run_callbacks :teardown, :enumerator => :reverse_each rescue Test::Unit::AssertionFailedError => e add_failure(e.message, e.backtrace) rescue *PASSTHROUGH_EXCEPTIONS raise rescue Exception add_error($!) end end result.add_run yield(Test::Unit::TestCase::FINISHED, name) end alias_method :run, :run_with_callbacks_and_testunit For miniunit: def run_with_callbacks_and_miniunit(runner) result = '.' begin run_callbacks :setup result = super rescue Exception => e result = runner.puke(self.class, self.name, e) ensure begin teardown run_callbacks :teardown, :enumerator => :reverse_each rescue Exception => e result = runner.puke(self.class, self.name, e) end end result end alias_method :run, :run_with_callbacks_and_miniunit "ugly hacks" as I said means that overriding existing method with using internal API and aliasing it. Example internal API is add_failure for test/unit case, runner.puke for miniunit. If test/unit and/or miniunit are/is easy to extend, active_support/testing/setup_and_teardown.rb doesn't need to overriding existing run method. > > miniunit doesn't provide extensible interface because it > > introduces complex mechanism. But we need it to avoid > > ugly hacks.(*) If miniunit keep simple, we will be dirty. > > I disagree. I've found a number of people (besides just me) that find > extending miniunit to be MUCH MUCH easier than test/unit. I rely on > basic idiomatic ruby to make miniunit much more approachable. See Phil > Hagelberg's previous email as evidence. > > Here is a real world (idiomatic) example of test/unit extension vs > miniunit: > > def assert_sorted(actual, message=nil, &block) > expected = actual.sort(&block) > message ||= "Expected order:\n#{expected.inspect}\nbut got order: > \n#{actual.inspect}\n" > assert_block(message) { expected == actual } > end > > vs: > > def assert_sorted(actual, message=nil, &block) > expected = actual.sort(&block) > assert_equal expected, actual, "Order is wrong:" > end I couldn't understand why test/unit version is: > def assert_sorted(actual, message=nil, &block) > expected = actual.sort(&block) > message ||= "Expected order:\n#{expected.inspect}\nbut got order:\n#{actual.inspect}\n" > assert_block(message) { expected == actual } > end We can write it same as miniunit version: > def assert_sorted(actual, message=nil, &block) > expected = actual.sort(&block) > assert_equal expected, actual, "Order is wrong:" > end > > I want users to be simple rather than testing framework is > > simple. > > I want both to be simple. These aren't mutually exclusive. I don't think so in many cases. It may be true in some cases. > > (*) How do we add new command line option? How do we get > > colorized output? How do we get diff between expected > > and actual values? Need another filter command? Need to > > overriding existing methods? It doesn't conflict with > > other extension? > > And you think that these are addressed better in test/unit? Tell me... > where in the files below does colorized output go? How about > commandline options? Filtering? > > % find . -name \*.rb | xargs grep -l Filter > ./unit/assertions.rb > ./unit/error.rb > ./unit/testcase.rb > ./unit/util/backtracefilter.rb > % find lib/test -name \*.rb | xargs wc -l > 14 lib/test/unit/assertionfailederror.rb > 622 lib/test/unit/assertions.rb # HERE? > 220 lib/test/unit/autorunner.rb > 107 lib/test/unit/collector/dir.rb > 34 lib/test/unit/collector/objectspace.rb > 43 lib/test/unit/collector.rb > 56 lib/test/unit/error.rb # HERE? > 51 lib/test/unit/failure.rb > 160 lib/test/unit/testcase.rb # HERE? > 80 lib/test/unit/testresult.rb > 76 lib/test/unit/testsuite.rb > 127 lib/test/unit/ui/console/testrunner.rb > 268 lib/test/unit/ui/fox/testrunner.rb > 416 lib/test/unit/ui/gtk/testrunner.rb > 465 lib/test/unit/ui/gtk2/testrunner.rb > 68 lib/test/unit/ui/testrunnermediator.rb > 46 lib/test/unit/ui/testrunnerutilities.rb > 260 lib/test/unit/ui/tk/testrunner.rb > 40 lib/test/unit/util/backtracefilter.rb # HERE? > 90 lib/test/unit/util/observable.rb > 48 lib/test/unit/util/procwrapper.rb > 280 lib/test/unit.rb > 3571 total > > % find lib/mini -name \*.rb | xargs wc -l > 31 lib/mini/mock.rb > 82 lib/mini/spec.rb > 436 lib/mini/test.rb # ALL HERE > 549 total colorized output: 127 lib/test/unit/ui/console/testrunner.rb # ALL HERE commandline options: 220 lib/test/unit/autorunner.rb # ALL HERE IMHO, putting all features in a large file isn't related to easy to extend. > > === miniunit just provides minimal features > > > > miniunit provides some advanced features: mock system and > > BDD style syntax. But they just provides limited > > functions. e.g. Mini::Mock can't handle multi expects for > > the same name. > > I don't really see how mini/spec is limited. I talked to David > Chelimsky at railsconf only feature it is really lacking from rspec is > nested contexts. I can't find a feature that is corresponding should_receive. IMHO, powerful mock support is the very useful feature in RSpec. And it seems that defining custom must_* method is a bother. Should we use Object.infect_with_assertions? > > Most of users prefer to useful system rather than simple > > system but limited features because they want to write their > > tests simply like Ryan wants miniunit to be simple. > > again... I'm not seeing this as a problem. miniunit is simple. it also > supports nearly every project out there already. For those that > require test/unit internals, things are actually cleaner now. They can > either require test/unit as a gem, or miniunit... it'll still work on > 1.8 and 1.9. > > > Most of users will use RSpec rather than Mini::Spec if they > > want to use BDD style syntax. > > yup. how is this a problem? This is only 82 lines of overhead. > > > Most of users will use Mocha or RSpec rather than Mini::Mock > > if they want to use a mock system. > > yup. how is this a problem? This is only 31 lines of overhead. I want said that: Their only has limited features. So their are not miniunit's benefits. They are needless features in the standard testing framework. They are just simple. > > Yes, I think that miniunit is very good solution for Ruby > > implementation developers because it has very small > > dependencies. It doesn't use standard libraries like > > OptionParser. But users doesn't require very small > > dependencies. They want useful tools rather than very small > > dependencies. > > again... I don't see small as bad. I didn't say that small is bad. I just said that too minimal is bad for users convenience. Thanks, -- kou