Thread overview
How does the integrated unittesting work?
Jul 28, 2004
Berin Loritsch
Jul 28, 2004
Ant
Jul 28, 2004
Sean Kelly
Jul 29, 2004
Berin Loritsch
Jul 29, 2004
Walter
Jul 29, 2004
Berin Loritsch
Jul 29, 2004
Arcane Jill
Jul 28, 2004
Ben Hinkle
July 28, 2004
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
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
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
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
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
"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
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
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