Tobiwan has asked for the wisdom of the Perl Monks concerning the following question:

Hi there,

I've to write a Test::More script and I've to send the output to an email-address. I catched the output but if any failure comes up, the Test called "exit()" and my script never reached the end.

Is there a chance to catch or to overwrite the exit() function? Or can I do some thinge, so that the Test-Module doesn't use exit()?

I try to redefine the CORE::exit-Function, but it doesnt work. I tried to define an exit()-function in EVERY package (I would wear sackcloth and ashes :) but nothing happend.

my $exit_sub = sub($) { die @_; }; sub _overwrite_exit { my $package = $_[0]; no warnings 'redefine'; no strict 'refs'; return if(*{"$package\::exit"}{CODE} && *{"$package\::exit"}{CODE} + == $exit_sub); #print "\n$package"; *{"$package\::exit"} = $exit_sub; foreach my $entry (keys %{"$package\::"}) { next if($entry !~ s/::$//); _overwrite_exit($entry); } } _overwrite_exit('main'); eval { print 123; exit(123); }; print "Test: $@"; # never reached!
Any useful ideas? I only have one sollution at the moment: create another script an call the testscript via system-call. But that has a bad taste for me...

Replies are listed 'Best First'.
Re: Use die() instead of exit() in Test::More
by kyle (Abbot) on Jun 14, 2007 at 14:08 UTC
      Thanks. That catch all handish exit() calls, but every BAIL_OUT(), from Test::More, results in an exit() like before.

      In the Test::Trap-Code I can't find any workarounds for the test-exits, so I'm as stupid as before :?

      How can I catch these Test::More-exits?

        Here's what I came up with:

        use Test::More 'no_plan'; open my $mail_pipe, '|-', 'cat > /tmp/pm' or die "Can't pipe: $!"; print $mail_pipe 'Test run: ', scalar localtime, "\n"; Test::More->builder->output( $mail_pipe ); Test::More->builder->failure_output( $mail_pipe ); ok( 1, 'one is true' ); ok( ! 0, 'zero is false' ); ok( 'roses', 'roses are read' ); ok( die(), 'violets are blue' ); ok( 'sugar', 'sugar is sweet' );

        The output from this when run is simply "Died at ...". Then /tmp/pm contains this:

        Test run: Thu Jun 14 10:19:57 2007 ok 1 - one is true ok 2 - zero is false ok 3 - roses are read 1..3 # Looks like your test died just after 3.

        In your case, instead of cat > /tmp/pm, open a pipe to something that will send the mail you want to send (such as 'mail' or 'sendmail'). When the exit happens, that pipe gets closed, and the mail gets sent. The only problem you might have is that if your mail sending program bombs, you'll never know it.

Re: Use die() instead of exit() in Test::More
by chromatic (Archbishop) on Jun 14, 2007 at 17:58 UTC

    This sounds like an XY Problem. How are you invoking your test file?

      Maybe, this is a XY problem :) I've to call the script direct via "perl testscript.pl", not via "prove".