unittesting generic functions

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Thu Aug 14 12:20:58 PDT 2014


On Thursday, 14 August 2014 at 04:04:11 UTC, H. S. Teoh via 
Digitalmars-d wrote:
> On Wed, Aug 13, 2014 at 06:10:54PM -0700, Andrei Alexandrescu 
> via Digitalmars-d wrote:
>> Destroy https://issues.dlang.org/show_bug.cgi?id=13291?
> [...]
>
> 1) How to add attributes to the unittest without them clashing 
> with the
> function's attributes?

It probably couldn't have any.

> 2) How to parse ddoc comments for the unittest?

I wouldn't expect it to make any sense to use a unittest block 
like that for documentation. The documentation examples are going 
to need specific types. It needs to be possible to actually try 
out the examples.

> 3) Where should unittest block stand in relation to in/out 
> contracts?

Does it matter? I don't know what  the current grammar says with 
regards to in and out - maybe it requires that in be before out - 
but I don't see any real reason to care about the order. Why not 
just let them be in any order as long as the body is last?

> 4) How much can you realistically test on a generic type 
> argument T,
> that you can't already cover with concrete types? I'm finding 
> that the
> per-instantiation behaviour of unittest blocks inside templated
> structs/classes is rarely desired, esp. when you write ddoc 
> unittests
> (because you want code examples in the docs to involve concrete 
> types,
> not abstract types, otherwise they are of limited use to the 
> reader).
> Because of this, I often move unittests outside the aggregate 
> or enclose
> them in static if's. This suggests that perhaps 
> per-instantiation
> unittests are only of limited utility.

I have _rarely_ found it to be useful to write generic tests 
inside of a template. It's a cute thing to be able to do and 
occasionally useful, but for the most part, I find it to be very 
annoying. For a templated function, it's not that big a deal, but 
for tremplated types, it's a nightmare. You're forced to put all 
of your unittest blocks outside of the struct or class, and you 
can't really use ddoc-ed unittest blocks. I'd actually prefer 
that the unittest blocks _didn't_ get generated for each 
instantation, but I think that that ship has unfortunately 
sailed, and it could be a bit of an implementation problem to 
have them not really be part of the template even though they're 
in it.

But aside from whether it's desirable for unittest blocks to be 
instantiated with the template or not, generating tests that way 
rarely makes much sense in my experience. Simple things like 
constructing the types involved and checking them agains the 
desired result just don't work, because you can't generically 
construct values of a type. Do you want [1, 2, 3, 4, 5], or 
["hello", "world", "goodbye"]? Those types invariably depend on 
what the template was instiated with, making the genericity not 
work for the tests.

I'm not necessarily against adding the proposed feature to the 
language, but it's just shorthand to avoid splitting out the 
template from the function, and I doubt that I'd ever use it.

- Jonathan M Davis


More information about the Digitalmars-d mailing list