April 16, 2017
http://code.dlang.org/packages/unit-threaded

Other than some bug fixes, the big news here is a version of the library that compiles a _lot_ faster: just add `"versions": ["unitThreadedLight"]` in `dub.json` or the equivalent for however you're building your project. If using dub, I suggest having two configurations: one for the regular unit-threaded build and another specifying `unitThreadedLight`.

So what's the catch? Pretty much that the features all go away. But: I realised that for the most part what one wants to do is just run all tests and know they all passed. All the advanced reporting, test naming, test selection etc. is only really useful when things _don't_ work. So I figured a trade-off would be to have a light mode that doesn't use compile-time reflection nor generates a bunch of code for each type to print out its value. Just use the default unittest runner and import the smallest possible number of modules. I even used printf instead of writeln to write out "Ok: All tests passed" because there was a measureble difference in compilation speed.

But what about all the custom `should` assertions? I replicated _all_ of them in the light mode by doing the bare minimum possible. Other things like mocking or property-based testing are hidden behind templates that only import the relevant modules if needed. I tested the influence on compile times between using `shouldEqual` and `assert`: it was small enough to not matter with the new version.

The result is a compile-time of about 0.2s on my machine (using dub adds another 0.2s on top of that or more if actually checking for dependencies) for a toy project with 200 unittest blocks. YMMV depending on how many advanced features you use. For instance, things like `@HiddenTest` and `@ShouldFail` will definitely not work. But, those could always be versioned away by checking for `unitThreadedLight`. If you compare this with the ~0.35s in compile time that it costs to write `import unit_threaded;` in the full-featured mode... never mind the ~1.1s to compile that toy project with the standard version.

I think the way I'll use this myself is to run the fast version by default when developing and switching to the slow version for debugging if it fails, automating this in a script like so:

# if the fast version fails run the slow one
dub run -q --nodeps -c ut || dub test -q --nodeps

This assumes there's a "ut" dub configuration specifying `unitThreadedLight` and `-unittest` and a "unittest" configuration that runs "normal" unit-threaded.

I haven't thoroughly tested the new mode though, so expect bugs. Good thing there's a fallback.

Atila