develooper Front page | perl.qa | Postings from January 2007

Re: Bad test functions in Test::Exception

Thread Previous | Thread Next
From:
Adrian Howard
Date:
January 31, 2007 01:01
Subject:
Re: Bad test functions in Test::Exception
Message ID:
D1EF2306-6FFC-4A84-9552-783B6A927A6F@quietstars.com
Hi Nadim,

On 30 Jan 2007, at 17:17, Nadim Khemir wrote:
[snip]
> The bad guys:
>
>   # Check that something died
>   dies_ok { $foo->method1 } 'expecting to die';
>
> Am I the only one who got this to pass, to find out later that what  
> cause the
> error had nothing to do with the message I displayed.
[snip]

For me this is like somebody complaining that:

   ok $o->answer, 'answer is 42'

passes when answer() return -1 :-) It's our job as developers to use  
the appropriate tests for the things we're interested in.

If you are interested in what has been specifically thrown use  
throws_ok. If you don't care use dies_ok.

> Checking that something
> dies is _not_ good enough. One should check more thorowly. Yes, I  
> know I can
> use throws_ok but why have dies_ok ? I'd say that dies_ok might  
> make your
> testing worse.

Emphasis on the "might". There are times when you don't know what  
kind of exception you'll be getting. There are times when you don't  
want to bind yourself to a particular exception format that's under  
the control of a third party piece of code. There are times when you  
know you'll be tweaking the exception format / classes during  
development so do not want to over specify a test. Sometimes you /do/  
just want to know whether something dies.

At least I do ;-)

> Use only the superior throws_ok.
>
>   # Check that something did not die
>   lives_ok { $foo->method2 } 'expecting to live';
>
> Is the above realy a test? Ok but testing what? why wouldn't we  
> wrap all our
> test in lives_ok? No, I don't think lives_ok makes any sense. I'd  
> be very
> happy to see real examples of lives_ok that add anything to a test  
> suite.

Okay.

One of the useful features of Perl's test framework is that we don't  
bail out on the first test failure so we can test a whole bunch of  
things at once like this:

foreach my $arg ( -9999 .. 9999 ) {
	lives_ok { $o->fribble( $arg ) } "fribble worked with $arg";
}

If we don't use lives_ok (or similar) then the script dies at the  
first failure, rather than running the rest of the tests.

>   # Check that a test runs without an exception
>   lives_and { is $foo->method, 42 } 'method is 42';
> Isn't this equivalent to is($foo->method, 42 , 'method is 42') ?  
> The test
> framework will catch the error if any. It's just weird to attempt  
> to catch
> something when the expected result is to pass.

Consider, like lives_ok, the cases where you don't want to abort the  
whole script in the case of failure.

>   # all Test::Exceptions subroutines are guaranteed to preserve the  
> state
>   # of $@ so you can do things like this after throws_ok and dies_ok
>   like $@, 'what the stringified exception should look like';
>
> This wouldn't be needed if dies_ok didn't exist.

Yes it would. It allows you to interrogate the exception after the  
test. For example:

throws_ok { $o->read_file( 'unreadable.txt' ) } 'UnreadableFile';
SKIP: {
     skip "no exception" => 1 unless my $e = $@;
     is $e->filename, 'unreadable.txt', 'exception captured filename';
}

> I postulate that Test::Exception would be even better if we removed  
> the bad
> guys.

As you can probably guess I disagree :-)

Cheers,

Adrian


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About