Named unittests and __traits(getModules)

Jacob Carlborg doob at me.com
Sun May 19 18:56:33 UTC 2019


I'm staring a new thread here on the topic of Name unittests because the 
existing one is getting too long [1].

The best way to add support for named unit tests, without adding any new 
syntax to the language, is to leverage UDAs. This has already been 
discussed in the previous post [1]. The problem with UDAs and the 
current unit test runner is by the time the unit test runner runs the 
unit tests, the UDAs are long gone. They need to be fetched at 
compile-time. It's also not possible to continue running unit tests in 
the same module after a failed unit test with the current runner. This 
is because the compiler generates one function that calls all the unit 
tests in the whole module.

To solve these problems `__traits(getUnitTests)` can be used to access 
the unit tests at compile-time. This leads to the next problem. To 
access the unit tests one needs to import the modules where the unit 
tests are defined. There are currently no way to get a list of all 
modules. Existing third party unit test runners usually use a pre-build 
script that collects all files with unit tests and generates a new file 
with all the imports. This is also noted in the previous thread [2].

The solution of running a pre-build script is not workable to include in 
druntime. I purpose we add two new traits: `__traits(getRootModules)` 
and `__traits(getImportedModules)`. `getRootModules` will return all 
root modules, i.e. the files which were passed to the compiler on the 
command line. `getImportedModules` will return all imported modules, 
i.e. the non-root modules. Adding these two together will give access to 
all modules the compiler has processed. Note that these traits are 
useful for other things than building a unit test runner.

With these two traits (only getRootModules might be necessary) and using 
`static foreach` to generate the imports, `getUnitTests` can later be 
used to retrieve the unit tests at compile-time which also gives access 
to the UDAs. Using this technique to run the unit tests allows to add 
additional features, like continue running after a failed test, before 
and after callbacks and other features.

There's already a unit test runner in the DMD test suite that uses this 
technique (but with the pre-build script). With these new traits this 
unit test runner could be added pretty easily to druntime.

Thoughts?

[1] https://forum.dlang.org/thread/mfcgj3$12a0$1@digitalmars.com
[2] https://forum.dlang.org/post/qbr7dd$16fd$1@digitalmars.com

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list