Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: Inverting test conditions in Test::More ?

by hippo (Bishop)
on Jul 24, 2020 at 09:59 UTC ( [id://11119745]=note: print w/replies, xml ) Need Help??


in reply to Inverting test conditions in Test::More ?

There doesn't seem to be a simple, generic way to negate an arbitrary test in Test::More AFAICT. But, if you are happy enough to dip your toe in the Test2::Suite waters:

use strict; use warnings; use Test2::V0; use Test2::Tools::Compare qw/is isnt/; my $w = { z => [ 0 .. 5 ] }; my $x = { z => [ 0 .. 5 ] }; my $y = { z => [ 1 .. 5 ] }; is ($w, $x, 'Match is good'); isnt ($x, $y, 'Not matching - also good'); done_testing;

🦛

Replies are listed 'Best First'.
Re^2: Inverting test conditions in Test::More ? (workaround)
by LanX (Saint) on Jul 24, 2020 at 11:06 UTC
    Thanks, finally someone accepting my question! :)

    > There doesn't seem to be a simple, generic way to negate an arbitrary test in Test::More AFAICT.

    I just realized that all tests return a boolean result.

    So here a workaround:

    use strict; use warnings; use Test::More; sub fail_ok (&;@) { my ($code,$description) = @_; my $result; TODO: { local $TODO= "should be silent"; my $result = $code->(); } $result ? fail($description) : pass($description); } fail_ok { is(1,2,"") } "Bingo! Test failed"; done_testing;

    The TODO block ensures that there is no failed test in the final result.

    But I still need to understand how to make the output of the failed inner test silent ... °

    ... I probably need to redirect the STDERR output of Test::Builder or fiddle with TAP altogether

    -*- mode: compilation; default-directory: "d:/exp/" -*- Compilation started at Fri Jul 24 13:02:20 C:/Perl_524/bin\perl.exe -w d:/exp/pm_negate_test.pl not ok 1 - # TODO should be silent # Failed (TODO) test '' # at d:/exp/pm_negate_test.pl line 21. # got: '1' # expected: '2' ok 2 - Bingo! Test failed 1..2 Compilation finished at Fri Jul 24 13:02:21

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

    °) Hmm... probably with subtests...

      Are you testing regular code, or testing other tests?

      If the former, why not just something like
      my $cond = 1 == 2; ok( $cond ); # fails ok( ! $cond ); # passes
      ... or whatever boolean condition.

      If the latter, Test::Builder::Tester seems designed to test other tests.

      To be fair, I could be misunderstanding - this is not a use case I've come across before.
        > If the former, why not just something like

        I'm looking for a generic approach, is_deeply is an example where its not that easy, but reiterating an example with is_deeply would lead the thread again into a different direction.

        So either I give a trivial example which is too easy or a complex where people are concentrating on the concrete example instead discussing the abstraction.

        > If the latter, Test::Builder::Tester seems designed to test other tests.

        Good call! looks promising, thanks. :)

        > Are you testing regular code, or testing other tests?

        Both. I already experimented with Test::Builder to generate another Test object redirecting the output.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

      > But I still need to understand how to make the output of the failed inner test silent ... °

      FWIW, this will silence the output, tho using a new Test::Builder object or using Test::Builder::Tester might be the better approach.

      use strict; use warnings; use Test::More; my $Test = Test::Builder->new; sub fail_ok (&;@) { my ($code,$description) = @_; # --- silence output my $ignore; $Test->output(\$ignore); $Test->failure_output(\$ignore); $Test->todo_output(\$ignore); my $result; TODO: { local $TODO= "should be silent"; #my $result = subtest "Negation of $description", $code; my $result = $code->(); } # --- undo silence $Test->reset_outputs; # --- output result $result ? fail($description) : pass($description); } fail_ok { is(1,2,"") } "Bingo! Test failed"; fail_ok { is(1,3,"") } "Bingo! Test failed again"; done_testing;

      C:/Perl_524/bin\perl.exe -w d:/exp/pm_negate_test.pl ok 2 - Bingo! Test failed ok 4 - Bingo! Test failed again 1..4

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (1)
As of 2024-04-19 00:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found