February 27, 2005
I was trying to further understand how unittests in D work,
and came up with the following small D example - and also
with an example on how it would look in Java using JUnit...

It tests a silly little example class called "Int",
which just wraps an int in a class and provides just
one method that actually does something: add(Int i);

Hope that it is useful for someone else too...


In Java, the test code goes in a test runner class
(or in a separate test hierarchy) so that it can be
left out of the final product. In D, it's in the class -
since D supports conditional compilation (and Java doesn't)

JUnit is a Java library, whileas unittest is a D built-in
(compares to how strings, arrays and other things work...)

There are some major caveats to watch out for in current D:
* main cannot return "void", or the test will always fail -
  since main will just return some funny non-zero value
* the code must be compiled with the -unittest flag and have
  assertions on (later DMD versions sets this automatically)
* all modules/classes to be test needs to be referenced
  manually, it order to invoke their unittest { } segment

But otherwise, they're not all *that* different...


Anyway, here's the code in Java:

Int.java:
> public class Int
> {
>     public Int(int value)
>     {
>         this.value = value;
>     }
> 
>     public int intValue()
>     {
>         return value;
>     }
> 
>     public Int add(Int i)
>     {
>         return new Int(value + i.intValue());
>     }
> 
>     public boolean equals(Object object)
>     {
>         if (this == object)
>             return true;
>         else if (object == null || getClass() != object.getClass())
>             return false;
>         Int i = (Int) object;
>         return intValue() == i.intValue();
>     }
> 
>     private int value;
> }


IntTest.java:
> import junit.framework.*;
> 
> public class IntTest extends TestCase
> {
>     public void testCreate()
>     {
>         Int i = new Int(0);
>         Assert.assertTrue( i.intValue() == 0 );
>     }
> 
>     public void testAdd()
>     {
>         Int i1 = new Int(1);
>         Int i2 = new Int(2);
>         Int i3 = new Int(3);
>         Assert.assertTrue( i1.add(i2).equals(i3) );
>     }
> 
>     public static Test suite()
>     {         return new TestSuite(IntTest.class);     }
> 
>     public static void main(String args[])
>     {         junit.textui.TestRunner.run(suite());
>     }
> }

Run with: java IntTest
> ..
> Time: 0,024
> 
> OK (2 tests)


And here is the corresponding code in D:

> public class Int
> {
>     public this(int value)
>     {
>         this.value = value;
>     }
> 
>     public int intValue()
>     {
>         return value;
>     }
> 
>     public Int add(Int i)
>     {
>         return new Int(value + i.intValue());
>     }
> 
>     public int opEquals(Object object)
>     {
>         if (this is object)
>             return true;
>         Int i = cast(Int) object;
>         if (object is null || i is null)
>             return false;
>         else
>             return intValue() == i.intValue();
>     }
> 
>     private int value;
> 
>     unittest
>     {
>         void testCreate()
>         {
>             Int i = new Int(0);
>             assert(i.intValue() == 0);
>         }
> 
>         void testAdd()
>         {
>             Int i1 = new Int(1);
>             Int i2 = new Int(2);
>             Int i3 = new Int(3);
>             assert(i1.add(i2) == i3);
>         }
> 
>         testCreate();
>         testAdd();
>     }
> }


IntTest.d:
> import std.stdio;
> 
> import Int;
> 
> int main(char[][] args)
> {
>     // Bring in unit test by referencing class
>     Int i = new Int(0);
> 
>     writefln("Unit Test successful");
>     return 0;
> }

Run with: ./IntTest && echo PASS || echo FAIL
> Unit Test successful
> PASS


For more info on JUnit, see http://www.junit.org/
There is a version available for C++ too, CppUnit.

xUnit also has a nice graphical test runner UI version:
http://junit.sourceforge.net/doc/testinfected/IMG00001.GIF
http://cppunit.sourceforge.net/cgi-bin/moin.cgi/MfcTestRunner

You can do something similar for D, by overriding _d_assert:
http://www.digitalmars.com/techtips/unittests.html

--anders

PS.
The Phobos 0.113 unittest still fails on Linux, format(734) :-(