perltestingcarp

Why won't prove accept -MCarp=verbose?


I ran this test script:

use strict;
use warnings;
use Test::More tests => 3;
use Carp;

ok(1<2);
pass();
fail();
croak "example";

using the command line prove -MCarp=verbose -v foo.pl, and got the following errors:

Subroutine App::Prove::verbose redefined at /opt/ActivePerl-5.12/lib/App/Prove.pm line 407
        App::Prove::_load_extension('App::Prove=HASH(0x683718)', 'Carp=verbose') called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 419
        App::Prove::_load_extensions('App::Prove=HASH(0x683718)', 'ARRAY(0x683850)') called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 481
        App::Prove::run('App::Prove=HASH(0x683718)') called at /opt/ActivePerl-5.12/bin/prove line 11
Undefined subroutine &Carp::verbose called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 484.

If I run it using perl -MCarp=verbose foo.pl there's no problem. What is causing prove to reject verbose Carp? How can I get a full callstack from my tests when they croak without global replacing croak to confess?


Solution

  • prove -M does not appear to be equivalent to perl -M. It appears to load a prove extension, not load a module into your tests. The docs are totally unclear on this point, but the code in App::Prove is not. So prove -MCarp=verbose imports Carp::verbose into App::Prove causing the problem above.

    A simple way to do what you want is to use the PERL5OPT environment variable plus Carp::Always which will turn all warns and dies (and carps and croaks) into stack traces.

    PERL5OPT=-MCarp::Always prove ...
    

    This has the added benefit of working in any situation, with or without prove.