D beginner's article about D's Metaprogramming and Testing

Steven Schveighoffer schveiguy at gmail.com
Thu Dec 21 02:55:45 UTC 2023


On Wednesday, 20 December 2023 at 18:39:12 UTC, Renato wrote:
> Perhaps "static if is evaluated at compile-time, and only the 
> branch that executes is present at runtime, i.e. the if 
> condition itself doesn't exist at runtime"?

Looks better now!

>> Regarding more descriptive unittests, try out the compiler 
>> parameter `-checkaction=context` to get more descriptive 
>> asserts: https://dlang.org/dmd-osx.html#switch-checkaction
>
> That would be awesome! But it seems there's some problem on my 
> machine:
>
> ```
> dmd -L-ld_classic -unittest -checkaction=context -run main.d
> Undefined symbols for architecture x86_64:
>   
> "__D4core8internal7dassert__T24miniFormatFakeAttributesTiZQBdFNaNbNiNfMKxiZAya", referenced from:
>       
> __D4core8internal7dassert__T14_d_assert_failTxiZ__TQxTiZQBcFNaNbNiNfMxAyaMKxiMxiZAya in main.o
>       
> __D4core8internal7dassert__T14_d_assert_failTmZ__TQwTiZQBbFNaNbNiNfMxAyaMKxmMxiZAya in main.o
> ld: symbol(s) not found for architecture x86_64
> clang: error: linker command failed with exit code 1 (use -v to 
> see invocation)
> Error: linker exited with status 1
>
> Compilation exited abnormally with code 1 at Wed Dec 20 19:34:11
> ```
>
> Do you know what this may be? Looks like the Mac OS's linker 
> just doesn't work well with the DMD compiler?!

 From your later message:

> I got this working, obviously I forgot the -main flag before... 
> too many flags to remember, I need to start using dub I suppose.

Great to hear, but man that is a *terrible* error message for 
such a thing! I wonder why this is the result? And what is 
"miniFormatFakeAttributes"?!

>
>> there are also options to build your own unittest runner, see 
>> https://dlang.org/phobos/core_runtime.html#.Runtime.extendedModuleUnitTester
>>
>> While this gives you only granularity of the module-level 
>> unittests, it allows you to do things like select only certain 
>> modules to run. And you do not need to build compile-time 
>> lists of all unittests yourself, the compiler links it all 
>> together for you (see the example in that function on what the 
>> default does).
>>
>
> Didn't I mention that in my blog post? Or is this not the same 
> as that example where I showed this:
>
> ```d
> Runtime.moduleUnitTester = &tester;
> ```

First, I did not see that you are using the module unit tester 
assignment, though it does make sense because that's how you 
override it.

But I should clarify that it is possible to override the unittest 
tester *and still* use the module unittests provided by the 
compiler. What you get is a function pointer per module to the 
unittest aggregate that calls all the individual unittests. And 
of course you have the module name.

So for example, if you wanted to catalog which modules run 
unittests, you do not need to use __traits(getUnittests). If you 
wanted to only run unittests from a given module/package based on 
runtime args, that also is possible. And the further advantage is 
that it works without having to use compile-time introspection to 
build the tester (i.e. you don't have to import all the testable 
modules).

I hope this makes things a bit clearer.

-Steve


More information about the Digitalmars-d mailing list