Ryan C. Thompson
Ryan C. Thompson

Reputation: 42020

How can I run a test in my Perl module's test suite only if the required module is installed?

I want to add a test to my Perl distribution that requires a module Foo, but my distribution does not require Foo; only the test requires Foo. So I don't want to add the module to the dependencies, but instead I just want to skip the tests that require Foo if Foo is not available at build time.

What is the proper way to do this? Should I just wrap my Foo tests in an eval block along with use Foo;, so that the tests will not run if loading Foo fails? Or is there a more elegant way of doing it?

Upvotes: 5

Views: 588

Answers (4)

daxim
daxim

Reputation: 39158

Also, declare your test step requirement or recommendation (there's a difference) in the distro meta file. This will be picked up by a client performing the installation. At install time, the user can decide whether to install such a requirement permanently or discard it because it was only used for testing.

Upvotes: 2

Matteo
Matteo

Reputation: 14930

From the documentation of Test::More:

SKIP: {
    eval { require HTML::Lint };
    skip "HTML::Lint not installed", 2 if $@;
    my $lint = new HTML::Lint;
    isa_ok( $lint, "HTML::Lint" );
    $lint->parse( $html );
    is( $lint->errors, 0, "No errors found in HTML" );
}

Upvotes: 2

hobbs
hobbs

Reputation: 239861

If all of the tests that require Some::Module are in a single file, it's easy to do:

use Test::More;

BEGIN {
    eval {
        require Some::Module;
        1;
    } or do {
        plan skip_all => "Some::Module is not available";
    };
}

(If you're using a test count like use Test::More tests => 42; then you need to also arrange to do plan tests => 42; if the require does succeed.)

If they're a smaller number of tests in a file that contains other stuff, then you could do something like:

our $HAVE_SOME_MODULE = 0;

BEGIN {
    eval {
        require Some::Module;
        $HAVE_SOME_MODULE = 1;
    };
}

# ... some other tests here

SKIP: {
    skip "Some::Module is not available", $num_skipped unless $HAVE_SOME_MODULE;
    # ... tests using Some::Module here
}

Upvotes: 8

Pradeep
Pradeep

Reputation: 3153

Test::More has an option to skip if some condition is not satisfied, see below

SKIP: {
    eval { require Foo };

    skip "Foo not installed", 2 if $@;

    ## do something if Foo is installed
};

Upvotes: 6

Related Questions