Hi all,
I am developing support for PhyloXML in BioRuby as Google Summer of Code
project. I have a question about unit testing.
My code depends on libxml-ruby library (other parts of BioRuby does
not). So
I want to test if libxml-ruby is required and then if it is not, i want
to
quit my unit test suite (a file tes_phyloxml.rb) nicely (don’t perform
any
unit tests related to phyloxml since they anyways gonna fail) but the
rest
of unit test suites should continue running.
Right now the it completely exits, if can’t load xml library, but I
would
like the other tests to continue running.
#First let’s test if xml library is here, since it will be required by
bio/db/phyloxml
begin
require ‘xml’
rescue LoadError
puts "Please install libxml-ruby library. It is needed for
Bio::PhyloXML
module. Unit tests will exit now.
exit 1
end
require ‘bio/db/phyloxml’
class TestPhyloXML1 < Test::Unit::TestCase
def setup
@phyloxml = Bio::PhyloXML.new(TestPhyloXMLData.example_xml)
end
def test_init
assert_equal(@phyloxml.class, Bio::PhyloXML)
end
#[…]
end
Thanks,
Diana
Hi –
On Tue, 30 Jun 2009, Diana J. wrote:
exit 1
def test_init
assert_equal(@phyloxml.class, Bio::PhyloXML)
end
#[…]
end
Maybe something like this, if it’s not too convoluted:
no_xml = false
begin
require ‘xml’
rescue LoadError
puts “No libxml; not running those tests…” # or whatever
no_xml = true
end
unless no_xml
class TestPhyloXML1
etc.
David
Thanks a lot! It worked like a charm!
Diana
On Tue, 30 Jun 2009, David A. Black wrote:
begin
require “xml”
rescue LoadError
puts “No xml library…”
else
class TestPhyloXML1 < Test::Unit::TestCase
…
end
end
OK, third time a charm.
begin
require ‘xml’
class TestPhyloXML1 < Test::Unit::TestCase
…
end
rescue LoadError
puts “No xml library…”
end
I think that’s as compact and streamlined as I can get it 
David
Hi –
On Tue, 30 Jun 2009, Diana J. wrote:
Thanks a lot! It worked like a charm!
Rob B., in another context, reminded me that
exception-handling blocks can have an “else” clause. So you could do
the slightly simpler:
begin
require “xml”
rescue LoadError
puts “No xml library…”
else
class TestPhyloXML1 < Test::Unit::TestCase
…
end
end
David
On Mon, Jun 29, 2009 at 4:07 PM, David A. Black [email protected]
wrote:
exception-handling blocks can have an “else” clause. So you could do
end
puts “No xml library…”
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (The Well-Grounded Rubyist)
“Ruby 1.9: What You Need To Know” Envycasts with David A. Black
http://www.envycasts.com
Yes indeed! Thanks!
Diana
Diana J. [email protected] wrote:
Thanks a lot! It worked like a charm!
else
class TestPhyloXML1 < Test::Unit::TestCase
…
end
rescue LoadError
puts “No xml library…”
end
I think that’s as compact and streamlined as I can get it 
Indeed - quite a while ago I wrote myself a utility for requiring
without penalty in case of failure, and here it is (as you’ll see, it
looks like a mere generalization of what David Black has already shown):
def myrequire(*what)
catch NameError
what.each do |thing|
begin
require((t = Array(thing))[0])
Array(t[1]).each {|inc| include self.class.const_get(inc)}
rescue LoadError
puts "Failed to locate required "#{thing}". "
puts $!
end
end
end
Here are some usage notes:
(1) no penalty for failure; we catch the LoadError and we don’t re-raise
(2) arg can be an array, so multiple requires can be combined in one
line
(3) array element itself can be a pair, in which case second must be
array of desired includes as symbols; that way, we don’t try to perform
the includes unless the require succeeded (and if an include fails, that
does raise all the way since we don’t catch NameError)
So, you might say e.g.
myrequire “pathname”, “yaml”, “erb”, “pp”, “uri”, “rubygems”, “exifr”
Or (an example with an include):
myrequire [‘rexml/document’, :REXML]
m.