http://www.perlmonks.org?node_id=689911

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

Replies are listed 'Best First'.
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]