Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Testing redirected croak messages

by macrobat (Beadle)
on Oct 27, 2005 at 22:18 UTC ( #503488=perlquestion: print w/replies, xml ) Need Help??

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

In a module, I have a function, lcroak(), that redirects croak messages to a logfile. This is called selectively, so regular croak messages go to STDERR if the user wishes. It works, and it works the way I expect it, by closing and reopening STDERR with a previously-selected filename as an argument.

Problem: I can't get it to pass my lcroak.t test. If I call lcroak directly, then the test dies, as you'd expect when you call croak. But that's considered a failure by Test::Harness's prove utility.

Alternately, I can throw an eval loop around the lcroak call. But that redirects croak messages into $@, so subsequent tests, to see if my redirection worked, fail.

Anyone see a way around this?

Replies are listed 'Best First'.
Re: Testing redirected croak messages
by chromatic (Archbishop) on Oct 27, 2005 at 23:12 UTC

    Does using Test::Exception work? If you don't want to do that, does using local on $@ within a block help?

      I'm not sure if I'm using Test::Exception right. Here's the gist of my original test, with the code in eval pulled out and switched to use dies_ok():

      unlink 'test.errors'; redirect_error( output_file => 'test.errors' ); # sets $redirected{err +or_messages} to 1 dies_ok { lcroak "this is a sample error file" }; ok( -T 'test.errors', "lcroak opens the error file specified by redirect_error()." ); my $text = `cat test.errors`; like( $text , qr/this is a sample error file/, "lcroak writes to the error file specified by redirect_error()." ) +; unlink 'test.errors';
      --and I get this:

      # Failed test 'lcroak writes to the error file specified by redirect +_error().' t/lcroak....NOK 4# in t/lcroak.t at line 25. # '' # doesn't match '(?-xism:this is a sample error file)' # Looks like you failed 1 test of 4.
      I did try local $@, like so, but perhaps I'm doing it wrong:

      { local $@; eval { lcroak "this is a sample error file"; }; ok($@, "lcroak terminates"); }
      That still redirect STDERR to test.error, however.

        It's difficult to say without seeing the code for lcroak() and redirect_error() (probably including the hash declaration).

Re: Testing redirected croak messages
by bluto (Curate) on Oct 27, 2005 at 23:54 UTC
    I'm probably missing something, but can you put the test in a separate process (e.g. qx() a separate script) and then grab and parse the STDERR output from that?
      I tried that with system() and it didn't work. I can try it with qx//, although I'm not sure what'll happen. Sorry I'm not too much with the specifics, I'm posting replies from elsewhere right now.
Re: Testing redirected croak messages
by xdg (Monsignor) on Oct 28, 2005 at 09:03 UTC

    Assuming your module takes over STDERR, and then relies on the behavior of croak (or, really, die) to write to STDERR, I don't think you'll get your tests to work with eval, which supresses the write to STDERR. You may be better off using a signal handler:

    local $SIG{__DIE__} = sub { local $|++; # autoflush print STDERR @_; }; unlink 'test.errors'; redirect_error( output_file => 'test.errors' ); # call this directly, not in an eval, as you're trapping the croak lcroak "this is a sample error file"; ok( -T 'test.errors', "lcroak opens the error file specified by redirect_error()." ); my $text = `cat test.errors`; like( $text , qr/this is a sample error file/, "lcroak writes to the error file specified by redirect_error()." ) +; unlink 'test.errors';

    Picking a nit -- cat test.errors isn't portable. You may want to use File::Slurp or the equivalent and keep it in Perl.

    Also, if you want to do this test by running a separate process, I'd suggest trying IPC::Run3 instead of using a system call. It will nicely redirect STDOUT and STDERR into scalar variables for you:

    run3 \@cmd, undef, \$out, \$err;

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Testing redirected croak messages
by macrobat (Beadle) on Oct 28, 2005 at 19:47 UTC
    Actually, the solution I came upon was to carp using redirection, reset STDERR to its original destination, and then croak. That way the log gets written before dying, and anything that causes failure also gets written to the terminal (if it's not redirected by the shell).

    Thanks everyone for the suggestions, though.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2022-11-30 23:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?