How can one reliably run unittests
H. S. Teoh
hsteoh at quickfur.ath.cx
Tue Aug 24 17:03:36 UTC 2021
On Tue, Aug 24, 2021 at 12:21:41PM +0000, deadalnix via Digitalmars-d wrote:
[...]
> Some of these component are libraries, some are executable. Adding a
> main for libraries is required, or it won't link, but adding one to
> executable is going to cause a link error. This in itself is a major
> main in the ass, because that means there is no one consistent way to
> unittest a module without knowing if that module has a main. In
> addition, everything needs to be built twice now, which is really
> undesirable.
There's the `-main` flag for adding an empty main() to the compiled
sources. But yeah, if there's already a main() it will die with a
compile error. The hack solution for this is to prepend this to your
main(), like this:
version(unittest){} else
void main() {
...
}
The point about building everything twice is legit, and is a pain point
I myself have come across. In the old days, -unittest used to just run
unittests before invoking main(). Then somebody changed this so that
-unittest causes main() not to run. So when coding/compiling/debugging,
I now need to build the program twice: once with -unittest, once
without.
Technically this isn't avoidable (no) thanks to `version(unittest)`: the
object files may have very different contents so compiling twice is
almost unavoidable. But in the normal, common case, there isn't *that*
much of a difference, and it would be nice to only have to compile once
(like in the old days).
> Maybe one could rdmd each modules to runt he tests? That seems like
> the best approach to me, considering one doesn't want to actually
> produce an artifact for the tests, simply run them. this also has the
> main/no main problem, but in addition, it often fails with
> incomprehensible linker errors. For some reason, rdmd is not able to
> include all dependencies consistently, but, even better, it doesn't
> take the same standard flags as other linkers do, so it is not
> possible to reuse existing build infrastructure to feed all the
> correct flags to rdmd.
Honestly, these days I find little need for rdmd. I can just run `dmd
-unittest -main -i -run main.d` and it will compile unittests, insert an
empty main(), and pull in all imports, run the resulting executable, and
clean up afterwards. Just a single command line takes care of it all.
Well, modulo the `version(unittest) else` hack for main().
> This may seems like it wouldn't be that big of a deal if you manage
> all your flags by yourself, but very quickly turns into a nightmare
> once you have to use 3rd party libraries that ship with their own set
> of flags.
Which means we need dub support for this. :-D
> At this point, I would just wish that one could rdmd --unittest
> modulename.d and just pass it a couple of -I, -L and -l flags and have
> all of it work. I have no idea how to achieve that.
[...]
As I already said:
dmd -unittest -main -i -run main.d
T
--
Only boring people get bored. -- JM
More information about the Digitalmars-d
mailing list