How can one reliably run unittests
deadalnix
deadalnix at gmail.com
Tue Aug 24 12:21:41 UTC 2021
D's unittest block is a great idea. However, I find that in
practice, I fail to make good use of them and have been
neglecting them. Sometime by using an external test suite
instead, sometime neglecting testing altogether. How come?
Well, the main reason is that, as far as I can tell, it is near
damn impossible to run them at scale in any sensible way. Let me
explain.
Ideally, one would want a module to be a unit. Declaration,
implementation, but also tests are part of the unit. During the
dev cycle, it is desired to be able to runt he test on modules to
verify that everything works as advertised. While doing so is
easy on a pet project,a s the projects grows, contains several
libraries and executable, doing this become very challenging.
It is not really possible to build a monster executable that
contains everything. First, this would kill build times, but,
with several main around it won't link. So let's split into
component.
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.
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.
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.
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.
This kind of orthogonality is important as a project scale. One
cannot just doctor all the unitests call to all the modules. You
need to be able to tell your build system something akin to "hey,
every time you encounter a D module, please implicitly add this
unitest target. Thanks." This cannot be made to work if running
unit tests is done in a way that depends on the content of the
module.
I don't think my case is isolated, every single substantial D
project I encountered has some kind of test suite or something
similar instead of relying on the unitests within modules. This
is frankly a failure, and it is 100% due to poor UX as the
language feature itself is great.
If someone has some bandwidth, it is IMO a high leverage task
that solve real problem for real people and 90% of the work is
already there. The feature is there, the runtime support &al is
there. just provide a consistent UX so its use can be integrated
properly in larger systems.
Thanks in advance.
More information about the Digitalmars-d
mailing list