www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Unit Test example, D vs. xUnit

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) :-(
Feb 27 2005