Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't prove accept -MCarp=verbose?

Tags:

testing

perl

carp

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?

like image 618
Philip Potter Avatar asked Dec 07 '22 01:12

Philip Potter


2 Answers

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.

like image 173
Schwern Avatar answered Dec 28 '22 23:12

Schwern


prove has a very different set of command line arguments than perl, being a completely different program?

prove's -M is, I believe, intended for enabling pragmas; Carp actually exports a forward reference to a verbose() subroutine, which interferes with prove's inner workings.

You can create a small module like this:

# Verbme.pm
use Carp;
$Carp::Verbose = 1;

and enable it from prove:

prove -MVerbme -v foo.pl

though.

like image 22
ysth Avatar answered Dec 28 '22 23:12

ysth