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

As part of the tests for Business::Stripe::Webhook I am getting an expected error on STDERR

C:\Users\Bod\Perl\Business-Stripe-Webhook\Business-Stripe-Webhook>prov +e -lv t/02-payload.t t/02-payload.t .. 1..6 ok 1 - Didn't instantiate ok 2 - Missing payload data ok 3 - Instantiated ok 4 - pay.invoice handled ok 5 - All webhooks handled Stripe Webhook Error: Invalid Stripe Signature ok 6 - Signature error ok All tests successful. Files=1, Tests=6, 1 wallclock secs ( 0.03 usr + 0.01 sys = 0.05 CPU +) Result: PASS

Does it matter that there is an error displayed between Tests 5 & 6?

Will it confuse people or automated installation scripts? If so, is there an accepted way to deal with this?

Replies are listed 'Best First'.
Re: STDERR in Test Results
by hippo (Archbishop) on Jun 18, 2023 at 20:09 UTC
      Why not test for it in that case?

      Simply because I didn't know about those Test modules...

        In that case may I suggest starting with Test::Warn? I find it the simplest of the three (and these are not the only three of course) as it has a very logically straightforward approach. Simply:

        use strict; use warnings; use Test::More tests => 1; use Test::Warn; # Your code which gives an expected warning sub foo { warn "Stripe Webhook Error: Invalid Stripe Signature\n"; } # Test your code warning_is { foo (); } "Stripe Webhook Error: Invalid Stripe Signature +\n", 'Invalid sig warning issued';

        Task::Kensho recommends Test::Warnings which is fine but a little more abstract. Both modules are widely used in other dists. I have found Test::Trap useful on occasion but it can take a bit of wrangling to set up properly.


        🦛

Re: STDERR in Test Results
by kcott (Archbishop) on Jun 18, 2023 at 17:59 UTC

    G'day Bod,

    The way I normally deal with this is along these lines:

    my $expected_error = 1; my $got_error = 0; eval { # code expected to die with error here 1; } or do { $got_error = 1; }; is $got_error, $expected_error, 'test name';

    — Ken

      Thanks kcott but that still generates the rogue output to STDERR

      I've tried this:

      my $got_warn = 0; eval { $webhook_fail->process(); } or do { $got_warn = 1; }; ok( $got_warn, "Signature warning generated"); ok( !$webhook_fail->success, "Signature error" );
      Both tests pass but I still get the output to STDERR when the process method is called.

      I guess I'm just looking for a way to suppress the output...

        "... expected error ... Webhook Error ... Signature error ... an error displayed ..."

        Originally, you repeatedly referred to an error; now you seem to have changed that to a warning. My solution traps errors, which you asked for; it doesn't trap warnings.

        $ alias perle alias perle='perl -Mstrict -Mwarnings -Mautodie=:all -MCarp::Always -E +' $ perle ' my $expected_error = 1; my $got_error = 0; eval { my @rgb = qw{#ff0000 #00ff00 #0000ff}; open my $fh, "<", "nonexistent_file"; 1; } or do { $got_error = 1; }; say "\$expected_error[$expected_error] \$got_error[$got_error]"; ' Possible attempt to put comments in qw() list at -e line 6. $expected_error[1] $got_error[1]

        Perhaps "warnings: Fatal Warnings" would help you.

        — Ken

        Update: Problem already found in Re^4: STDERR in Test Results.


        Both tests pass but I still get the output to STDERR when the process method is called. I guess I'm just looking for a way to suppress the output...

        Or perhaps for a place where someone prints to STDERR or warns.

        Looking at B::S::W 1.11 at CPAN, B::S::W::process() calls $self->_error() with the error message shown. And now look at that method:

        sub _error { my ($self, $message) = @_; $self->{'error'} = $message; if (defined &{$self->{'error'}}) { &{$self->{'error'}}($message); } else { STDERR->print("Stripe Webhook Error: $message\n"); } }

        That's why you shall use warn and die instead of printing to STDERR. sub _warning has the same problem.


        Oh, by the way: eval catches errors, not warnings, so your variable would be better named $got_error instead of $got_warn.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: STDERR in Test Results
by SankoR (Prior) on Jun 18, 2023 at 19:37 UTC
    If the output is expected, it's probably safe to ignore it. According to the spec, TAP parsers shouldn't choke on unexpected output to STDERR so smokers and module installers like cpanm should be okay.

    It's an extra test phase dependency but if you're determined to make sure that auth error triggers, you could verify it with something like Test::Output.