Hack to name unit tests?

Robert Fraser fraserofthenight at gmail.com
Thu Nov 29 17:01:33 PST 2007


Christopher Wright wrote:
> 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");
> }
Heh; alright; that's what I was looking for! Thanks!



More information about the Digitalmars-d mailing list