How to interrupt unit tests if a library is not present.

Discussion in 'Ruby' started by Diana Jaunzeikare, Jun 29, 2009.

  1. [Note: parts of this message were removed to make it a legal post.]

    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

    --
    I blog here: latvianlinuxgirl.blogspot.com
    Diana Jaunzeikare, Jun 29, 2009
    #1
    1. Advertising

  2. Hi --

    On Tue, 30 Jun 2009, Diana Jaunzeikare wrote:

    > 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


    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

    --
    David A. Black / Ruby Power and Light, LLC
    Ruby/Rails consulting & training: http://www.rubypal.com
    Now available: The Well-Grounded Rubyist (http://manning.com/black2)
    "Ruby 1.9: What You Need To Know" Envycasts with David A. Black
    http://www.envycasts.com
    David A. Black, Jun 29, 2009
    #2
    1. Advertising

  3. [Note: parts of this message were removed to make it a legal post.]

    Thanks a lot! It worked like a charm!

    Diana

    On Mon, Jun 29, 2009 at 12:10 PM, David A. Black <> wrote:

    > Hi --
    >
    >
    > On Tue, 30 Jun 2009, Diana Jaunzeikare wrote:
    >
    > 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
    >>

    >
    > 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
    >
    > --
    > David A. Black / Ruby Power and Light, LLC
    > Ruby/Rails consulting & training: http://www.rubypal.com
    > Now available: The Well-Grounded Rubyist (http://manning.com/black2)
    > "Ruby 1.9: What You Need To Know" Envycasts with David A. Black
    > http://www.envycasts.com
    >
    >
    Diana Jaunzeikare, Jun 29, 2009
    #3
  4. Hi --

    On Tue, 30 Jun 2009, Diana Jaunzeikare wrote:

    > Thanks a lot! It worked like a charm!


    Rob Biedenharn, 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

    --
    David A. Black / Ruby Power and Light, LLC
    Ruby/Rails consulting & training: http://www.rubypal.com
    Now available: The Well-Grounded Rubyist (http://manning.com/black2)
    "Ruby 1.9: What You Need To Know" Envycasts with David A. Black
    http://www.envycasts.com
    David A. Black, Jun 29, 2009
    #4
  5. On Tue, 30 Jun 2009, David A. Black wrote:

    > Hi --
    >
    > On Tue, 30 Jun 2009, Diana Jaunzeikare wrote:
    >
    >> Thanks a lot! It worked like a charm!

    >
    > Rob Biedenharn, 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


    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

    --
    David A. Black / Ruby Power and Light, LLC
    Ruby/Rails consulting & training: http://www.rubypal.com
    Now available: The Well-Grounded Rubyist (http://manning.com/black2)
    "Ruby 1.9: What You Need To Know" Envycasts with David A. Black
    http://www.envycasts.com
    David A. Black, Jun 29, 2009
    #5
  6. [Note: parts of this message were removed to make it a legal post.]

    On Mon, Jun 29, 2009 at 4:07 PM, David A. Black <> wrote:

    > On Tue, 30 Jun 2009, David A. Black wrote:
    >
    > Hi --
    >>
    >> On Tue, 30 Jun 2009, Diana Jaunzeikare wrote:
    >>
    >> Thanks a lot! It worked like a charm!
    >>>

    >>
    >> Rob Biedenharn, 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
    >>

    >
    > 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
    >
    > --
    > David A. Black / Ruby Power and Light, LLC
    > Ruby/Rails consulting & training: http://www.rubypal.com
    > Now available: The Well-Grounded Rubyist (http://manning.com/black2)
    > "Ruby 1.9: What You Need To Know" Envycasts with David A. Black
    > http://www.envycasts.com
    >
    >

    Yes indeed! Thanks!

    Diana
    Diana Jaunzeikare, Jun 30, 2009
    #6
  7. Diana Jaunzeikare

    Matt Neuburg Guest

    Diana Jaunzeikare <> wrote:

    > [Note: parts of this message were removed to make it a legal post.]
    >
    > On Mon, Jun 29, 2009 at 4:07 PM, David A. Black <> wrote:
    >
    > > On Tue, 30 Jun 2009, David A. Black wrote:
    > >
    > > Hi --
    > >>
    > >> On Tue, 30 Jun 2009, Diana Jaunzeikare wrote:
    > >>
    > >> Thanks a lot! It worked like a charm!
    > >>>
    > >>
    > >> Rob Biedenharn, 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
    > >>

    > >
    > > 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 :)


    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.
    Matt Neuburg, Jun 30, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark
    Replies:
    1
    Views:
    399
    Christopher Blunck
    Aug 13, 2003
  2. Replies:
    8
    Views:
    885
  3. Ralf Wahner
    Replies:
    5
    Views:
    627
    Bob Foster
    Dec 24, 2003
  4. Vahagn Hayrapetyan
    Replies:
    3
    Views:
    166
    Vahagn Hayrapetyan
    May 2, 2011
  5. dayo
    Replies:
    11
    Views:
    338
    Ilya Zakharevich
    Dec 16, 2005
Loading...

Share This Page