unittests and templates
Steven Schveighoffer
schveiguy at yahoo.com
Tue May 11 13:06:31 PDT 2010
A cool thing I learned on the way to d2.
unittests can be templatized just like the classes/structs they reside
in. When enhancing dcollections with lots of detailed unit tests, I was
doing things like this:
class ArrayList(V)
{
V take() {...}
unittest
{
auto al = new ArrayList!uint;
al.add([0u, 1, 2, 3, 4]);
assert(al.take() == 4);
assert(al.length == 4);
}
}
But I found that the unittests weren't compiling -- at all! What I
realized is that unittests are part of the instantiation!
At first, I was peeved, I wanted to simply test the "take" function not
caring what type I used to instantiate the class with. In order to do
that, I have to move all the unit tests outside the class declaration --
not good for maintainability.
But I came to realize -- there is great power in that feature. For
example, with a little change to my unit test:
unittest
{
auto al = new ArrayList;
al.add([cast(V)0, 1, 2, 3, 4]);
assert(al.take() == 4);
assert(al.length == 4);
}
I can create a global unit test that looks like this:
unittest
{
ArrayList!uint al1;
ArrayList!int al2;
ArrayList!ulong al3;
ArrayList!long al4;
}
and now my unit tests cover 4 instantiations. With a single line, I can
extend my unittest coverage to another type!
Of course, the issue is, how do I write a truly generic unit test? For
example, that 'take' unit test fails for ArrayList!string. If I wanted to
compile a project that happened to include the string instantiation with
unit tests turned on, it fails to compile.
The ugly solution is to use static if like so:
static if(isIntegral!V)
{
unittest
{
}
}
But that is, well, ugly. I thought of proposing something like:
unittest if(isIntegral!V)
{
}
which looks better, but still is a bit verbose. This might be the
cleanest solution. Any suggestions?
I still would like a way to do a unittest inside a template that is
technically not part of the instantiation. This allows you to unit test a
function with a specific instantiation when it's not easy to build a
generic unit test *and* you want the unit test close to the function
declaration. Although it's bloaty, you could just write your unittests
like I did originally, specifying the full type in the unit test, but you
then have to remember to create an external unit test to do the
instantiation.
I hate to suggest static unittest :P Any other ideas?
-Steve
More information about the Digitalmars-d-learn
mailing list