== Dunit: Unit Testing for D == Chances are, you're familiar with D's existing unittest features. Given that the language has builtin tests, why would you need an addon library for testing? === Unit testing with unittest {} === Builtin unittest {} blocks are simply sections of code that are executed before main and after any static constructors. They are only compiled and executed when you pass in the -unittest parameter to dmd. They offer more functionality than testing strictly requires. This strategy has a few issues: * It is difficult to integrate into a continuous integration setup because main() is still run and you have to replace it when running unittests. * Unittests are not labeled. * A failing test will prevent any other tests from running. This is due to the integrated test runners in Phobos and Tango. * A failing test in a module will prevent any other tests in that module from running. This is a language issue -- all the unittests in a module are aggregated into one function. * There is no output that specifically indicates that the tests were run. * If the tests are slow, there is no indication that the tests are in progress, and no indication of which one is running slowly. * There is no indication of which test failed, if any. * There is no structure to a unittest, so it's difficult to reuse common setup code. It also has a few strong points: * It's easy to learn. * Unit testing is quick -- it doesn't require any setup. * It's convenient to add tests in the same module as the code that is being tested. * You can't run your application if you have broken tests (unless you recompile). I believe that unittest {} blocks are very well suited to small (one-module) programs, much more so Dunit. === Unit testing with Dunit === Dunit tests involve creating a class that inherits from TestFixture and adding tests to that class. This allows for a much richer testing strategy, but it has its weak points: * Since Dunit is a library, you need to import it, which you likely don't want to do with production code, due to licensing issues if nothing else. * If you write Dunit tests in separate modules, while your production code doesn't include dunit, you cannot test private methods. Dunit encourages the practice of separating tests and modules. * You have to write a bit more code to test with Dunit. * It takes a few minutes to learn how to use Dunit. (That said, you should know just about all there is to know inside an hour.) But Dunit offers a number of benefits: * All tests are named. * If one test fails, all the other tests will run. * You can see progress from the tests as they are being run. * If an exception is thrown from a test, the name of the test and the exception message will be printed, along with a stacktrace (if you use a stacktrace tool). * With a builtin xml output system, Dunit integrates much better with continuous integration systems. * Tests have more structure, so it is easier to enforce standards in testing and to reuse common code in multiple tests. Dunit also offers an alternate assertion system, much like NUnit's. You can use this with unittest {} blocks as well as Dunit tests. === Downloads === See the [wiki:Downloads] page. === See also === * UnitTesting * [wiki:Assertions] (Assertion system from the last stable release) * [wiki:Assertions2] (Assertion system from the current release) * [wiki:ParameterizedTesting] Testing with generated data