View mode: basic / threaded / horizontal-split · Log in · Help
July 28, 2004
How does the integrated unittesting work?
It's not easy finding examples that really show you how valid
unit tests are built in D, or how to run them.  I am lacking the
big picture on them.  I see that there is syntax to support the
feature, but beyond that, I am at a loss.

I am used to JUnit, where I have distinct classes, and the test
runner will collect the tests in the classes and execute all the
individual tests.  The results of the tests can then be integrated
with the IDE, presented graphically, or HTML reports made from
them.

The ease of extending JUnit to do what you want is pretty attractive.
However, I am very curious how these things are supposed to work in D.

The fact that D is supposed to have unit test support built in is
a really nice idea.  Since I have been infected by TDD practices,
I want to continue that as I delve into D.

Is there a tutorial, or can someone break it down for me?
July 28, 2004
Re: How does the integrated unittesting work?
In article <ce9614$lnv$1@digitaldaemon.com>, Berin Loritsch says...
>
>It's not easy finding examples that really show you how valid
>unit tests are built in D, or how to run them.

(warning - all this from memory)

unittest are run before main().
as are static this() ctors.
remember that when you have a prog that segfaults before the first
statement on main() ;)

must compile with the flag -unittest.

check std.string for examples.

Ant
July 28, 2004
Re: How does the integrated unittesting work?
In article <ce9614$lnv$1@digitaldaemon.com>, Berin Loritsch says...
>
>Is there a tutorial, or can someone break it down for me?

# // test.d
# 
# int calc( int x, int y ) { return x * y; }
# 
# unittest
# {
#     printf( "Unit tests running\n" );
#     assert( calc( 1, 1 ) == 1 );
#     assert( calc( 1, 2 ) == 2 );
#     assert( calc( 6, 4 ) == 24 );
#  }
#
# int main() { return 0; }

From the command line:

c:\> dmd -unittest test.d
c:\> test
Unit tests running

c:\>

When a program is compiled with the unittest switch, all unit tests will be
evaluated when the program is executed.  If any of the unit tests fail, you will
get an assert error with the line number.  If they all succeed then the program
will run as normal.  The basic idea is that you create a set of tests to verify
that your code works.  In most cases I try to choose inputs based on knowledge
of how the function works so I can test things that might break it.  For a
fairly involved example, look at format.d in Phobos.


Sean
July 28, 2004
Re: How does the integrated unittesting work?
Berin Loritsch wrote:

> It's not easy finding examples that really show you how valid
> unit tests are built in D, or how to run them.  I am lacking the
> big picture on them.  I see that there is syntax to support the
> feature, but beyond that, I am at a loss.
> 
> I am used to JUnit, where I have distinct classes, and the test
> runner will collect the tests in the classes and execute all the
> individual tests.  The results of the tests can then be integrated
> with the IDE, presented graphically, or HTML reports made from
> them.
> 
> The ease of extending JUnit to do what you want is pretty attractive.
> However, I am very curious how these things are supposed to work in D.
> 
> The fact that D is supposed to have unit test support built in is
> a really nice idea.  Since I have been infected by TDD practices,
> I want to continue that as I delve into D.
> 
> Is there a tutorial, or can someone break it down for me?

I'd like to add to other replies that the unittest support in D is very
simple - all the unit tests get run at startup and the first that fails
stops execution. To get fancy stuff like logging, error recovery, test
filtering, etc you'd probably have to write a test harness and write your
unit tests to interact with the test harness. Or modify the function
_moduleUnitTests in src/phobos/std/moduleinit.d to do whatever you want.

-Ben
July 29, 2004
Re: How does the integrated unittesting work?
Sean Kelly wrote:

> In article <ce9614$lnv$1@digitaldaemon.com>, Berin Loritsch says...
> 
>>Is there a tutorial, or can someone break it down for me?
> 
> 
> # // test.d
> # 
> # int calc( int x, int y ) { return x * y; }
> # 
> # unittest
> # {
> #     printf( "Unit tests running\n" );
> #     assert( calc( 1, 1 ) == 1 );
> #     assert( calc( 1, 2 ) == 2 );
> #     assert( calc( 6, 4 ) == 24 );
> #  }
> #
> # int main() { return 0; }
> 
> From the command line:
> 
> c:\> dmd -unittest test.d
> c:\> test
> Unit tests running
> 
> c:\>
> 
> When a program is compiled with the unittest switch, all unit tests will be
> evaluated when the program is executed.  If any of the unit tests fail, you will
> get an assert error with the line number.  If they all succeed then the program
> will run as normal.  The basic idea is that you create a set of tests to verify
> that your code works.  In most cases I try to choose inputs based on knowledge
> of how the function works so I can test things that might break it.  For a
> fairly involved example, look at format.d in Phobos.

This is a bit different than what I would expect...

I am used to running unit tests as a function of compilation (i.e. run
right after compile), and not before each time I run the software.

In a sense, this adds to the perceived startup time of any D program.
Asserts are great and all, but what about mock objects?  I have found
that for methods/functions that pull info or call functions on other
objects passed in, the mock object approach works wonders.  All I really
want to do is test by setting the known value to return from the
dependency, or throw an exception from certain methods to ensure the
one under test handles the boundary conditions well.

I am not clear on how to do that with D--unless we just include a bunch
of classes that have no bearing on the application...
July 29, 2004
Re: How does the integrated unittesting work?
"Berin Loritsch" <bloritsch@d-haven.org> wrote in message
news:ceaqrj$1d31$1@digitaldaemon.com...
> I am used to running unit tests as a function of compilation (i.e. run
> right after compile), and not before each time I run the software.

There's no way to run unittests before the software is compiled and linked.

> In a sense, this adds to the perceived startup time of any D program.

Only if you compile with -unittest. Presumably, in a production release, you
wouldn't, and the unittests will be left out of the release build.

> Asserts are great and all, but what about mock objects?  I have found
> that for methods/functions that pull info or call functions on other
> objects passed in, the mock object approach works wonders.  All I really
> want to do is test by setting the known value to return from the
> dependency, or throw an exception from certain methods to ensure the
> one under test handles the boundary conditions well.
>
> I am not clear on how to do that with D--unless we just include a bunch
> of classes that have no bearing on the application...

Why not make a separate module with all the mock classes in it, and not link
it in for the release builds?
July 29, 2004
Re: How does the integrated unittesting work?
Walter wrote:

> "Berin Loritsch" <bloritsch@d-haven.org> wrote in message
> news:ceaqrj$1d31$1@digitaldaemon.com...
> 
>>I am used to running unit tests as a function of compilation (i.e. run
>>right after compile), and not before each time I run the software.
> 
> 
> There's no way to run unittests before the software is compiled and linked.

That's common sense.  All I was saying is that as soon as the
compilation/linking stage is done--that is when I expect the unit tests
to be run.  Not necessarily when I execute the software.

> 
> 
>>In a sense, this adds to the perceived startup time of any D program.
> 
> 
> Only if you compile with -unittest. Presumably, in a production release, you
> wouldn't, and the unittests will be left out of the release build.

Right.

> 
> 
>>Asserts are great and all, but what about mock objects?  I have found
>>that for methods/functions that pull info or call functions on other
>>objects passed in, the mock object approach works wonders.  All I really
>>want to do is test by setting the known value to return from the
>>dependency, or throw an exception from certain methods to ensure the
>>one under test handles the boundary conditions well.
>>
>>I am not clear on how to do that with D--unless we just include a bunch
>>of classes that have no bearing on the application...
> 
> 
> Why not make a separate module with all the mock classes in it, and not link
> it in for the release builds?

:) Ok, I have to figure out how to do that...

First things first, though.
July 29, 2004
Re: How does the integrated unittesting work?
In article <cebk2v$1n7e$1@digitaldaemon.com>, Berin Loritsch says...
>
>That's common sense.  All I was saying is that as soon as the
>compilation/linking stage is done--that is when I expect the unit tests
>to be run.  Not necessarily when I execute the software.

In a way, D does even better than your expectations. You don't want the tests to
be run when the software is executed; well, DMD distinguishes between a debug
build and a release build, and in a release build, the unit tests are not run -
and, /even better/, are not even compiled in, so your executable gets smaller.

It's easy enough (in a debug build) to get unit tests to run immediately after
compilation - just tweak your makefile or build script or whatever you use so
that it executes the program after linking. (main() will execute after the unit
tests, but you can feed it whatever command line parameters it takes to persuade
main to return immediately).

Arcane Jill
Top | Discussion index | About this forum | D home