new features of test unit 2.x
DESCRIPTION
Review of the new features of Test::Unit 2.x for RubyTRANSCRIPT
New Features of Test::Unit 2.0New Features of Test::Unit 2.0
Daniel BergerDaniel Berger
Ruby, C, PerlRuby, C, PerlWin32UtilsWin32Utils
SysUtilsSysUtilsShardsShards
SapphireSapphire
Test::Unit now a gemTest::Unit now a gem
Maintained by Kouhei SutouMaintained by Kouhei Sutou gem install test-unitgem install test-unit
I Do Not KnowI Do Not Know
RSpecRSpec ShouldaShoulda If your favorite testing framework already If your favorite testing framework already
supports the features I discuss, greatsupports the features I discuss, great If not, perhaps you’ll want to borrow themIf not, perhaps you’ll want to borrow them
How to use Test::Unit 2.xHow to use Test::Unit 2.x
require ‘rubygems’require ‘rubygems’ gem ‘test-unit’gem ‘test-unit’ require ‘test/unit’require ‘test/unit’
New AssertionsNew Assertions
assert_trueassert_true assert_falseassert_false assert_booleanassert_boolean
assert_trueassert_true
assert_true(condition)
Same as:
assert_equal(true, condition)
assert(condition)
assert_falseassert_false
assert_false(condition)
Same as:
assert_equal(false, condition)
assert_booleanassert_boolean
assert_boolean(result)
Same as:
assert_equal(true, [true, false].include?(result))
WowWow
Ooh, aah.Ooh, aah.
New stuff to use within testsNew stuff to use within tests
omit()omit() omit_if()omit_if() omit_unless()omit_unless() pend()pend() notify()notify()
omit, omit_if, omit_unlessomit, omit_if, omit_unless
Used to skip tests entirelyUsed to skip tests entirely
Or in specific circumstancesOr in specific circumstances
Omit ExamplesOmit Examplesclass TC_MyTest < Test::Unit::TestCase def test_alpha omit("Buggy library. Skip") # never reach past here assert_true(1 == 1) end
def test_beta omit_if(File::ALT_SEPARATOR, "Skipping test on MS Windows") # Won’t run this test on MS Windows (or VMS) assert_true(1 == 1) end
def test_gamma omit_unless(File::ALT_SEPARATOR, "Only run on MS Windows") # Won’t run this test except on MS Windows assert_true(1 == 1) endend
OutputOutput
1) Omission: Buggy library. Skiptest_alpha(TC_MyTest)omit_examples.rb:7:in `test_alpha'
2) Omission: Skipping test on MS Windowstest_beta(TC_MyTest)omit_examples.rb:12:in `test_beta'
3 tests, 1 assertions, 0 failures, 0 errors, 0 pendings, 2 omissions, 0 notifications
Only 1 assertion ran, the other two were skipped
pendpend
The Test::Unit version of a TODO itemThe Test::Unit version of a TODO item But better, because a TODO in code is But better, because a TODO in code is
easily forgotten, but a pending test will easily forgotten, but a pending test will annoy you into completing it.annoy you into completing it.
pend examplepend exampleclass TC_MyTest < Test::Unit::TestCase def setup @obj = MyClass.new end
def test_alpha pend("The 'alpha' function hasn't been implemented yet") assert_true(@obj.alpha) endend
1) Pending: The 'alpha' function hasn't been implemented yettest_alpha(TC_MyTest)pend_example.rb:13:in `test_alpha'
1 tests, 0 assertions, 0 failures, 0 errors, 1 pendings, 0 omissions, 0 notifications
notifynotify
A notification within your testA notification within your test Unlike typical stdout, tracked by Test::Unit Unlike typical stdout, tracked by Test::Unit
as its own entityas its own entity Possibly useful as a test debugger (?)Possibly useful as a test debugger (?)
notify examplenotify exampleclass TC_MyTest < Test::Unit::TestCase def test_alpha notify("starting the alpha test") assert_true(1 == 1) notify("finished the alpha test") endend
1) Notification: starting the alpha testtest_alpha(TC_MyTest)notify_example.rb:7:in `test_alpha'
2) Notification: finished the alpha testtest_alpha(TC_MyTest)notify_example.rb:9:in `test_alpha'
1 tests, 1 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 2 notifications
startup and shutdownstartup and shutdown
Analogous to startup and teardown, Analogous to startup and teardown, except that they only run once per test except that they only run once per test casecase
As opposed to once per testAs opposed to once per test Oh, and they’re singleton methodsOh, and they’re singleton methods Use for things you only need to do once, Use for things you only need to do once,
e.g. file generation, database connections, e.g. file generation, database connections, etcetc
startup & shutdown examplestartup & shutdown exampleclass TC_MyTest < Test::Unit::TestCase def self.startup @@file_name = File.join(Dir.pwd, 'my_test_file.txt') @@file_handle = File.open(@@file_name, 'w') end
def test_file_path assert_respond_to(@@file_handle, :path) end
def self.shutdown @@file_handle.close File.delete(@@file_name) endend
Don’t forget the ‘self’
multiple setup & teardownmultiple setup & teardown
You can have multiple setup and teardown You can have multiple setup and teardown methods with their own namemethods with their own name
Each setup runs in the order declared, Each setup runs in the order declared, before any tests are runbefore any tests are run
Each teardown runs in Each teardown runs in reverse orderreverse order declaration after all tests have rundeclaration after all tests have run
Useful for breaking out big chunks of setup Useful for breaking out big chunks of setup and teardown code into their own, and teardown code into their own, manageable piecesmanageable pieces
multiple setupsmultiple setupsclass TC_MyTest < Test::Unit::TestCase def setup # first @standard = MyClass.new end
setup # second def setup_alpha @alpha = MyClass.new end
setup # third def setup_beta @beta = MyClass.new end
def test_stuff assert_true(1 == 1) endend
multiple teardownsmultiple teardowns
class TC_MyTest < Test::Unit::TestCase def test_stuff assert_true(1 == 1) end
def teardown # last @standard = nil end
teardown # second def teardown_alpha @alpha = nil end
teardown # first def teardown_beta @beta = nil endend
Setup AttributesSetup Attributes setup :before => :prependsetup :before => :prependRuns before default setupRuns before default setup
setup :before => :appendsetup :before => :appendRuns before default setup, but after before/prependRuns before default setup, but after before/prepend
setup :after => :prependsetup :after => :prependRuns after default setup, but before after/append and Runs after default setup, but before after/append and
custom setup methodscustom setup methods
setup :after => :appendsetup :after => :appendRuns after default setup and after custom setup methodsRuns after default setup and after custom setup methods
Attribute ‘before’Attribute ‘before’class TC_MyTest < Test::Unit::TestCase def setup # Third puts "In setup" end
setup # Fourth def setup_alpha puts "In setup_alpha" end
setup :before => :prepend # First def setup_beta puts "In setup_beta" end
setup :before => :append # Second def setup_gamma puts "In setup_gamma" endend
Quick Rules SummaryQuick Rules Summary
1.1. setup :before => :prependsetup :before => :prepend2.2. setup :before => :appendsetup :before => :append3.3. setup (default)setup (default)4.4. setup :after => :prependsetup :after => :prepend5.5. setup (custom)setup (custom)6.6. setup :after => :appendsetup :after => :append
Get it? Got it? Good.Get it? Got it? Good.
Better Diff OutputBetter Diff Output
1) Failure:test_string_diff(TC_MyTest) [diff_example.rb:7]:<"weird"> expected but was<"wierd">.
1) Failure:test_string_diff(TC_MyTest) [diff_example.rb:7]:<"weird"> expected but was<"wierd">.
diff:- weird? -+ wierd? +
Old:
New:
Priority ModePriority Mode
Adds a –priority-mode command line Adds a –priority-mode command line optionoption
If used, failed tests always repeatIf used, failed tests always repeat Tests that passed previously have a 50% Tests that passed previously have a 50%
chance of runningchance of running Designed to reduce your test timeDesigned to reduce your test time Can be controlled with Can be controlled with prioritypriority pragma pragma
Sample Priority OutputSample Priority Output 1) Failure:test_one(TC_MyTest) [priority.rb:47]:<true> expected but was<false>
2) Failure:test_two(TC_MyTest) [priority.rb:51]:<true> expected but was<false>
7 tests, 7 assertions, 2 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
1) Failure:test_one(TC_MyTest) [priority.rb:47]:<true> expected but was<false>
2) Failure:test_two(TC_MyTest) [priority.rb:51]:<true> expected but was<false>
6 tests, 6 assertions, 2 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
Forcing a testForcing a test
priority :mustdef test_blah assert_true(1 == 1)end
This test will always run, regardless of the “–priority-mode” switch.
Priority ModesPriority Modes
must (i.e. always)must (i.e. always) importantimportant highhigh normalnormal lowlow NeverNever
Not sure what the probabilities are, and it doesn’t Not sure what the probabilities are, and it doesn’t matter.matter.
Colorized OutputColorized Output
On by default (bad)On by default (bad) Disable with –no-use-colorDisable with –no-use-color Doesn’t work on Windows (yet)Doesn’t work on Windows (yet)
Any questions?