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

Dear Monks,

I've decided to write proper test scripts for the modules I'm developing. I've checked Test::Simple and Test::More, and they're missing a feature that seems important for me : not_ok() function. I need to test that my subs work OK, but it's perhaps at least as important to check that they fail properly when feeded with bad data!
Test::More allows failed tests in a TODO: block, but that's not what I'm looking for. Does any of you know how I may solve this elegantly?

# this one should work ok( my_sub('needs', 3, 'parameters'), "that's good!"); # this one should fail not_ok(my_sub('bad parameter count'), "that fails!");

Replies are listed 'Best First'.
Re: Test::More : I'd need a "not_ok()" function...
by castaway (Parson) on Oct 14, 2005 at 15:21 UTC
      You saved my life :) All possible perl programs are already written, but you'll have to find out where first :)
Re: Test::More : I'd need a "not_ok()" function...
by inman (Curate) on Oct 14, 2005 at 14:41 UTC
    Just negate the test. 'ok' is looking for the test to succeed. If you are testing a sub and are looking for it to fail then re-write the test such that the failure of the sub is a succesful test.
    # this one should succeed when the sub fails ok(!my_sub('bad parameter count'), "Bad param test");
Re: Test::More : I'd need a "not_ok()" function...
by philcrow (Priest) on Oct 14, 2005 at 14:48 UTC
    Using a negated test works great, if your sub returns false for the error.

    Lately, Damian has been urging us to die when things go wrong. If my_sub follows that advice, then you need more than a negated test. You need an eval like this:

    eval { my_sub( 'bad param count' ); }; is( $@, 'your error message', 'test name' );
    Which supports the OP's point that a not_ok might be in order, but only to test for a correct death message.
      That's exactly what's happening to me! my_sub('bad') actually dies, that's my problem... a not_ok() would allow less cluttered test scripts than  eval {...}; is($@, 'something', 'test');
      I dare trying using a good ol' ugly prototype :
      sub not_ok(&$) { my $coderef = shift; my $message = shift; eval $coderef; ok( $@, $message) } # call this way not_ok( sub { mysub('bad data') }, 'message')
      How do you find this? Not refined, but works.
        I wouldn't call it 'not_ok', as that suggests 'ok !'. You want to test it dying, so I'd call it something like: 'die_cmp' (for exact testing of the die message) or 'die_like' (for regex testing of the die message).
        Perl --((8:>*
        I'm no expert on the internals of Test::More, but your method looks fine to me. I would follow the previous suggestion and call it die_ok or something similar. The maintainers usually have good opinions about the names.

        Phil

        The main problem with this is that the routine you are testing *must* die. You can't use it for tests that just return 0 for failure (i.e. the opposite of what "ok()" does). Perhaps it should be named something like "should_die"?

        Also, you may want to use 'like()' instead of 'ok()' if you are matching a die message that contains dynamic information (e.g. filename, line number, stack trace, etc).