Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Issues when testing module loading

by skx (Parson)
on Jun 03, 2008 at 15:30 UTC ( #689911=perlquestion: print w/ replies, xml ) Need Help??
skx has asked for the wisdom of the Perl Monks concerning the following question:

I've been a long-term user of test cases for my own code, as that gives me confidence that my code is good - or at the very least that changes I introduce haven't broken things too much!

My test-cases, in general, have been fairly straightforward in nature, and have worked without issues. As a matter of course I try to document the requirements of my code via a test case modules.t, which should ensure that anybody who can make the test case run successfully (via "make test") has all the modules required.

Here is an explicit example:

#!/usr/bin/perl -w -I.. # # Test that all the Perl modules we require are available. # (This list is automatically generated.) use Test::More qw( no_plan ); # ... BEGIN{ use_ok( 'CGI' ); } require_ok( 'CGI' ); BEGIN{ use_ok( 'Date::Format' ); } require_ok( 'Date::Format' ); BEGIN{ use_ok( 'POSIX' ); } require_ok( 'POSIX' ); # ... # ...

This test is part of a series which runs, via cron, on a daily basis. Unfortunately the combination of modules which I'm testing for give me a whole bunch of spam on STDERR:

skx@gold:~$ perl t.t > /dev/null Subroutine main::ctime redefined at (eval 4) line 2 Prototype mismatch: sub main::ctime ($;$) vs none at (eval 4) line 2 Subroutine main::strftime redefined at (eval 4) line 2 Prototype mismatch: sub main::strftime ($\@;$) vs none at (eval 4) lin +e 2 Subroutine main::asctime redefined at (eval 4) line 2 Prototype mismatch: sub main::asctime (\@;$) vs none at (eval 4) line +2

So, my question. Is it possible for me to avoid these errors whilst still working in the "standard" way when it comes to using Test::More and testing module availability?

(Certainly I accept that making my crontab entry throw away STDERR would solve my immediate problem, but it might hide things from me in the future.)

Steve
--

Comment on Issues when testing module loading
Select or Download Code
Re: Issues when testing module loading
by moritz (Cardinal) on Jun 03, 2008 at 15:36 UTC
    When you test your modules, don't test if the prerequisites work - your Makefile.PL should test if they are available, and their specific test suites should check that they work the way they are expected to.

    So just test use_ok 'Your::Module';.

    (I know that doesn't answer the underlying question of how to test module loading; if you just want to silence these warnings, use no warnings qw(redefine prototype);)

      Thanks for that reply - yes if I were distributing things using a Makefile.PL then this would be a non-issue. But right now I distribute things as Debian packages, and raw .tar.gz files.

      (This particular case came up when I made a new release of my chronicle blog compiler.)

      Changing my test case to read as follows still fails though:

      #/usr/bin/perl -w # use strict; use warnings; no warnings "all"; use Test::More qw( no_plan ); BEGIN{ use_ok( 'CGI' ); } BEGIN{ use_ok( 'Date::Format' ); } BEGIN{ use_ok( 'POSIX' ); }
      Steve
      --
        my bad, warnings only effects the lexical scope, and the warnings are generated inside the POSIX module.

        One workaround is to explicitly only import a non-conflicting sub BEGIN{ use_ok( 'POSIX', 'setsid' ); }. Or use require_ok, which doesn't import anything.

        Or don't test for POSIX at all, it's been core since perl 5, and not likely to go away any time soon.

Re: Issues when testing module loading
by andreas1234567 (Vicar) on Jun 04, 2008 at 07:04 UTC
    The source of these warnings is that both POSIX and Date::Format happen to export the same subroutine names into the main:: namespace by default, such as sub strftime:
    $ perl use strict; use warnings; no warnings "all"; use Test::More tests => 2; BEGIN { use_ok('POSIX', 'strftime'); } BEGIN { use_ok('Date::Format', 'strftime'); } __END__ 1..2 ok 1 - use POSIX; Prototype mismatch: sub main::strftime: none vs ($\@;$) at /usr/lib/pe +rl5/5.8.5/Exporter.pm line 65. at (eval 4) line 2 ok 2 - use Date::Format; $
    Exporter says
    Exports pollute the namespace of the module user. If you must export try to use @EXPORT_OK in preference to @EXPORT and avoid short or common symbol names to reduce the risk of name clashes.
    In your case I guess it comes down to selectively exporting only those functions you are going to use, while carefully making sure you don't get any namespace collisions.

    I think it is bad practice of Date::Format to export a subroutine name by default that collides with another subroutine name from a package that is included in core perl. A possible patch to Format.pm could be:

    $ diff Format.pm.org Format.pm 15c15 < @EXPORT = qw(time2str strftime ctime asctime); --- > @EXPORT_OK = qw(time2str strftime ctime asctime);
    --
    No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://689911]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (9)
As of 2014-12-21 20:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (107 votes), past polls