Section 16.3. Using the Ruby Debugger


16.2. The ZenTest Tools

Ryan Davis is the author of this excellent suite of tools. The main tool itself (zentest) is an executable that actually reads your code and produces a file of tests.

The class under test (CUT) is used as the basis for the test class (TC). The string Test is appended to the front of the class name at each scope level; the methods are named by appending test_ to the front of each name. Method names may also need to be "mangled" if they are methods such as == (which can't have anything prefixed) or if they end in ?, !, or =.

Listing 16.2 shows a sample piece of code to be tested:

Listing 16.2. Class to Be Tested

class Alpha   class Beta     attr_accessor :foo, :bar     def initialize     end     def foo?       @foo     end   end   def initialize   end   def process   end   def process!   end   def ==(other)   end   def ===(other)   end end

Run the command zentest file.rb >tfile.rb and you will get the code shown in Listing 16.3 as output.

Listing 16.3. Output from ZenTest

# Code Generated by ZenTest v. 3.2.0 #                 classname: asrt / meth = ratio% #               Alpha::Beta:    0 /    7 =  0.00% require 'test/unit' unless defined? $ZENTEST and $ZENTEST class TestAlpha < Test::Unit::TestCase   def test_process     raise NotImplementedError, 'Need to write test_process'   end   def test_process_bang     raise NotImplementedError, 'Need to write test_process_bang'   end end module TestAlpha   class TestBeta < Test::Unit::TestCase     def test_bar       raise NotImplementedError, 'Need to write test_bar'     end     def test_bar_equals       raise NotImplementedError, 'Need to write test_bar_equals'     end     def test_foo       raise NotImplementedError, 'Need to write test_foo'     end     def test_foo_eh       raise NotImplementedError, 'Need to write test_foo_eh'     end     def test_foo_equals       raise NotImplementedError, 'Need to write test_foo_equals'     end   end end # Number of errors detected: 9

Notice how each test method is given a raise call so that it will fail. The concept is that all tests fail by default until you write code to make them pass.

For whatever reason, the original file is not pulled into the test file. You can add require 'file' or the equivalent to the top of your test file (after requiring test/unit). Then all of your class definitions will be available to your test code.

Note that it's possible to put a second parameter on the command line. If you add code to your classes under test, your test classes are out of date. Rather than update them by hand, you can generate only the "new" material in this way:

zentest file.rb tfile.rb >tfile2.rb


The unit_diff program is another useful tool that is part of this suite. Consider the simple assertion assert_equal("foo","bar"). This will produce output such as the following:

  1) Failure: testme(Foo) [(irb):7]: <"foo"> expected but was <"bar">.


That is simple and clear. But suppose the strings passed in were each multiple lines in length, and the difference was only on the seventh line. The unit_diff tool is the solution to an unreadable mess of that kind. It does a UNIX-like "diff" operation and displays the output. Invoke it as a filter on your usual test program:

ruby testfile.rb | unit_diff


It knows a few command-line switches:

-h  Help (usage) -v  Version -b  Ignore whitespace differences -c  Do a contextual diff -k  Keep temp diff files around -l  Prefix line numbers on the diffs -u  Do a unified diff


The autotest tool hovers over your test suites in daemonlike fashion and runs those that have changed recently. This is for the person who is too lazy even to type a filename to run the tests.

To use this tool, you have to obey its naming conventions. The rules are simple:

  • All tests live under a test directory.

  • Test filenames start with test_.

  • Test class names start with Test.

  • Your code to be tested lives under the lib directory.

  • Files under lib must have corresponding test files (prefixed with test_, of course).

When you start autotest, it will cycle through your tests as they are updated. When it finds one that fails, it is smart enough to run it repeatedly until you fix it. It will start over "from the top" when you press Ctrl+C and will quit when you press Ctrl+C a second time.

The tool called multiruby enables you to test your code against multiple versions of Ruby. It is part of the ZenTest suite, but at the time of this writing it is not completely stable nor well documented.




The Ruby Way(c) Solutions and Techniques in Ruby Programming
The Ruby Way, Second Edition: Solutions and Techniques in Ruby Programming (2nd Edition)
ISBN: 0672328844
EAN: 2147483647
Year: 2004
Pages: 269
Authors: Hal Fulton

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net