Hack to name unit tests?
Christopher Wright
dhasenan at gmail.com
Thu Nov 29 13:03:11 PST 2007
Robert Fraser wrote:
> Christopher Wright wrote:
>> Robert Fraser wrote:
>>> I'm creating a Flectioned-based way to run unit tests individually
>>> (it'll be hooked into a front-end, so you can run test suites, repeat
>>> only failed tests after a code change, etc.)
>>>
>>> However, I have run into a problem: unit tests can't be named. Right
>>> now I have a signature system, but I was wondering if there's any
>>> hackish way to predictably insert a string into the generated object
>>> file in a way that users can name unittests. That is to say, given a
>>> function pointer, is there any way I can scan the code to see if a
>>> name has been given to the unit test, and if so extract that name at
>>> runtime?
>>>
>>> Ideally, it'd be as easy for the user as something like:
>>>
>>> unittest
>>> {
>>> assert(":testName:");
>>> // Rest of test goes here...
>>> }
>>>
>>> Right now, I have the associations being done in the front-end I'm
>>> working on, that scans the code for comments in a particular format
>>> and associates those with the unit tests. However, that ties the unit
>>> test executor back-end to the code analysis front-end, so I was
>>> hoping there's a better way.
>>>
>>> Thanks!
>>
>> class Unittest (string _name, alias _dg) : IUnittest {
>> static string name = _name;
>> static void delegate() test = _dg;
>> }
>>
>> Usage:
>> Unittest!("my test for wossname", {
>> assert (false, "haven't gotten around to implementing this yet");
>> });
>>
>> Not guaranteed to work.
>>
>> Another tactic would be something like:
>>
>> class UnittestManager {
>> static void registerCurrentTest (string name) {}
>> static void endTest (bool success) {}
>> static bool performTest () {}
>> }
>>
>> template Unittest (string _name, alias _dg) {
>> unittest {
>> UnittestManager.registerCurrentTest(_name);
>>
>> // This lets us skip the test if we're just trying
>> // to find out what tests there are currently.
>> if (UnittestManager.performTest) {
>> scope(success) UnittestManager.endTest(true);
>> scope(failure) UnittestManager.endTest(false);
>> _dg();
>> }
>> }
>> }
>>
>> mixin Unittest!("my test name", { assert (false, "not yet
>> implemented"); });
>
> Thanks! That's a good idea, but I want something compatible with current
> unittest {} declarations.
You already have to modify the tests to insert the name, but you want
something that works as a decorator inside the unittest. Can your
unittest runner do a try/catch on a unittest? Then you could have
something like:
void testName(string name) {
if (collectingNames)
throw new UnittestNameException(name);
}
struct NamedTest {
Unittest test;
string name;
}
...
void main () {
NamedTest[] tests;
collectingNames = true;
foreach (test; getUnittests) {
try {
test();
} catch (UnittestNameException e) {
tests ~= NamedTest(test, e.name);
}
}
collectingNames = false;
}
unittest {
testName("blargh");
assert (false, "still working on this");
}
More information about the Digitalmars-d
mailing list