View mode: basic / threaded / horizontal-split · Log in · Help
February 07, 2005
unittest vs release builds
OK, so we've pretty much discussed release
versus non-release in that other thread...
(recap: -release strips out all contracts)

Now, how do I apply unit testing to the
final (-release) builds of the modules ?


Currently, from what I can see in Phobos,
the unittest sections looks something like:

>     s = std.string.format(1.67, " %A ", -1.28, float.nan);
>     assert(s == "1.67 -0X1.47AE147AE147BP+0 nan");

That is, the unittest is done by using assert.
I'd better leave that -release flag out, then!


Because if I add the -release flag, then besides
skipping array bounds and switch default checks,
it will also strip out the assertions. Such as
the one doing the actual unittest verification...

What if I do something silly in one of my contracts,
such as introducing side effects that affect the
result of the function/class/module being tested ?
(side effects in assert/in/out/invariant is a no-no)


Then the unittest could run OK, since it is still
using the contracts which "rig" the unittest outcome.
But when I aim for the "-O -inline -release" build,
then both the contracts and the unittests are out...

And instead I am left with a spectacular crash, due to
some lame programming error I thought I had checked for ?
(Even if I did apply all my defensive programming skills to
check all user and outside input, using regular Exceptions)


Of course, all of this is just splitting hairs and one could
just argue that -release should imply cutting out all of the
contracts and the bounds checks and the unit tests altogether.
But it's not like DMD stops me, when doing "-unittest -release"?


1)
The current implementation should *require* contracts on, in
order to perform the unittest! Otherwise you just end up with
something like the Phobos library tests, that aren't checked...

Or, at the very least, just "assert" by itself:
> --- mars.c.orig Sat Jan 15 00:58:12 2005
> +++ mars.c      Mon Feb  7 10:15:34 2005
> @@ -371,6 +371,10 @@
>         global.params.useSwitchError = 0;
>      }
>  
> +    if (global.params.useUnitTests)
> +    {  global.params.useAssert = 1;
> +    }
> +
>      if (global.params.link)
>      {
>         global.params.exefile = global.params.objname;

Otherwise the tests could just silently be skipped over...


2)
I would also be nice if all the regular programs returned
EXIT_SUCCESS, so that one could interpret EXIT_FAILURE...

Currently, this *always* fails - as far as the shell knows:
> void main()
> {
> 
> }
> 
> unittest
> {
>   assert(0);
> }

Whether I am using -unittest or not, due to the "void main()"
(If I use "int main() { return 0; }" , then it works OK...)

void main should implicitly do a return 0; back to the runtime.
(I already submitted a patch to sanity-check main's return type)

--anders
February 07, 2005
Re: unittest vs release builds
Anders F Björklund wrote:

[...]
> Then the unittest could run OK, since it is still
> using the contracts which "rig" the unittest outcome.
> But when I aim for the "-O -inline -release" build,
> then both the contracts and the unittests are out...
[...]

Thanks for pointing this out. Whatever direction D will go, the 
decision seems to be restrained to one of
1) restrict the contracts to non assignments
2) risk bugs when building a release.

-manfred
Top | Discussion index | About this forum | D home