Hack to name unit tests?

Don Clugston dac at nospam.com.au
Sat Dec 1 00:50:35 PST 2007


Robert Fraser wrote:
> Don Clugston 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...
>>> }
>>
>> I think this is possible, but tricky. If your unit test has a local 
>> variable, and you instantiate a template using that local variable as 
>> an alias parameter, the module and the number of the unit test gets 
>> included into the mangled name.
>> This means that it's possible for code to know which unit test it is 
>> inside.
>> By making the template a class, you could to walk the RTTI list and 
>> make a lookup table to associate test numbers with their names. If you 
>> can get the list  of unittest numbers from flectioned, you can join it
>>
>> BUT... that's all pretty hairy. Maybe there's a less convoluted way of 
>> doing it.
> OK; _that's_ what I was looking for, since the test doesn't need to be 
> run that way... time to get hacking!

Unfortunately, templated class don't show up in the normal class list accessable 
through moduleinit.d, so it's you'll need to use flectioned for that too.

Here's the simplest example I came up with which displays the module and unit 
test number (taken from my now-defunct NameOf module -- hmmm, might be worth 
rescuscitating a couple of ideas from it; it's much easier now we have CTFE).
It only works if you've defined a local variable to use as an alias, which is a 
bit annoying.

---
template testname(alias F) { enum testname { ignore }  }
template TESTNAME(alias K) {
    typedef void function(testname!(K)) TESTNAME;
}

unittest {
     int foo;
     pragma(msg, TESTNAME!(foo).mangleof[3..$-13]);
}
----------



More information about the Digitalmars-d mailing list