Running unittests in a D library

Johannes Pfau nospam at example.com
Thu Sep 20 03:34:50 PDT 2012


Am Wed, 19 Sep 2012 12:34:18 -0700
schrieb Jonathan M Davis <jmdavisProg at gmx.com>:

> On Wednesday, September 19, 2012 20:50:08 Chris Molozian wrote:
> > Hey all,
> > 
> > I'm sure that this is a rather daft question but I've tried to
> > search the d.learn mailing list and must have missed a question
> > about it.
> > 
> > I've read the unit testing documentation on dlang.org and I know
> > that `unittest { /* some code */ }` blocks are compiled into the
> > executable and executed after static initialization and before
> > the main() function is called. This makes sense in an application
> > but how does this apply to a library?
> > 
> > For example, writing a D library using DMD's `-lib` compiler
> > flag, how do I run the unit tests in the generated library?
> 
> You don't build it as a library when your unit testing it. You create
> an empty main, compile it all as an executable, and run it. I believe
> that rdmd --main will do this for you (rdmd comes with dmd), but I
> haven't really used rdmd, so I'm not 100% certain.
> 
> - Jonathan M Davis

But it should be possible. A pointer to the unittests is kept in the
ModuleInfo so you'd have to get all the module infos of the library.
There's actually no reason it wouldn't work, static libraries are just
an archive of .o files. But the compiler must explicitly disable
unittests when it's called with "-lib" as this example shows:

test1.d
-----
import std.stdio;

unittest
{
    writeln("test1.unittest");
}

-----

main.d
-----
import test1;

void main(){}
-----

dmd -lib test1.d -unittest
dmd main.d -unittest test1.a
./main //no output

dmd -c test1.d -unittest
dmd main.d -unittest test1.o
./main //OK

dmd -c test1.d -unittest
ar r test1.a test1.o
dmd main.d -unittest test1.a
./main //OK

The problem is this: Druntime must be able to get a reference to the
ModuleInfo. So the linker must not remove the unittests in the library,
so it might be necessary to import all modules with unittests from
main.d.


This situation sucks, but it could get better with shared libraries: If
a shared lib is built with --unittest all unittest functions are
compiled in. We don't have to worry about the linker removing stuff for 
dynamic libraries. Then a unittest runner could dlopen the library,
search for all ModuleInfos (this is a little diffficult, but we'll need
it for plugins/reflection anyway) and run all unittests in the library.


More information about the Digitalmars-d-learn mailing list