help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: TDD in Octave, guidance/tutorial?


From: Jordi Gutiérrez Hermoso
Subject: Re: TDD in Octave, guidance/tutorial?
Date: Tue, 5 Feb 2013 08:58:40 -0500

On 5 February 2013 07:01, IainIsm <address@hidden> wrote:
> On 4 February 2013 18:08, Jordi Gutiérrez Hermoso-2 [via Octave]
> <[hidden email]> wrote:
>>
>> On 4 February 2013 12:29, IainIsm <[hidden email]> wrote:
>> > For example I have started to write a function which requires two
>> > parameters and then can accept optional parameters, provided as a
>> > pair:
>> >
>> > getAccelData(required1, required2)
>> > getAccelData(required1, required2, optional1, optional2)
>> [snip]
>> > !!!!! test failed
>> > No matching property found for: test
>>
>> How are you writing getAccelData? Are you using inputParser?

> Hi - I am (was?) using a homebrew approach, but now I've looked up
> inputParser I might just use that instead (thank you)!
>
> In the meantime, from the documentation at
> http://www.gnu.org/software/octave/doc/interpreter/Test-Functions.html I was
> expecting that the following MWE would test successfully:

The following what?

> function output = mustBeZero(input)
> if (input ~= 0)
>   error('Non-zero input!')
> end
> output=input;
>
> %!test fail(mustBeZero(1));
> %!test assert(mustBeZero(0), 0);
>
> But what I get is:
>
> octave:29> test mustBeZero verbose
>>>>>> L:\octave\testing\mustBeZero.m
>   ***** test fail(mustBeZero(1));
> !!!!! test failed
> Non-zero input!
>
> But this doesn't match what I understood from the documentation since an
> 'expected failure' is occurring?

You have to understand that the Octave parser is very, very dumb.

In particular, under any circumstance, when you write

   foo(bar(1))

and foo and bar are functions, bar will get evaluated before foo no
matter what foo is. There isn't a way for the foo function to create
some sort of context in which bar(1) is evaluated specially (e.g. like
a try-catch block). So in your test above, mustBeZero(1) is evaluated
first, an error gets thrown, and control never reaches the fail()
function.

Instead, the fail() function expects a string, like so:

    fail("mustBeZero(1)")

and internally uses evalin to evaluate this string in a special
try-catch context:

    
http://hg.savannah.gnu.org/hgweb/octave/file/59715612ea72/scripts/testfun/fail.m#l85

> After a lot of playing the only way I can get the 'expected failure' test to
> pass is to use xtest:
>
> %!xtest fail(mustBeZero(1));

Unlike fail, the test and xtest do evaluate their code in a special
context. In effect, the %! blocks are not evaluated by the interpreter
directly, but by specialised code that later passes on the code to the
Octave interpreter, similar to evalin inside a try-catch block.
Therefore, and %!xtest block automatically stringifies its contents
before evaluating, so it can catch the mustBeZero(1) error. This is
therefore equivalent to your test above:

    %!xtest mustBeZero(1)

> (Perhaps what I've found is a problem with the clarity of the
> documentation?)

Suggest alternative wording, and I will incorporate it into the
manual.

- Jordi G. H.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]