<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">As unittesting came up again I will use the occasion to pump up again blip.rtest ;).<div>It is a randomized unittest framework.</div><div><br></div><div>see&nbsp;<a href="http://petermodzelewski.blogspot.com/2009/02/tango-conference-2008-rolling-dice.html">http://petermodzelewski.blogspot.com/2009/02/tango-conference-2008-rolling-dice.html</a></div><div><br></div><div>The basic idea is to make writing testing functions easy: you write things that generate inputs for your testing functions (for example file path, random strings, matrix/vector,...)</div><div>To add a structure or a class it is enough to implement</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>static MyType randomGenerate(Rand r)</div><div>or</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>static MyType randomGenerate(Rand r,ref bool acceptable)</div><div>or (if you have also a combinatorial, non random part)</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;static MyType randomGenerate(Rand r,int idx, ref int nEl, ref bool acceptable)
</div><div><br></div><div>For many types you already have predefined generators.</div><div>Then you write testing functions that use these arguments:</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>void myTestFunction(MyType arg1,int arg2,...){ ...}</div><div><br></div><div>and create test collections using&nbsp;autoInitTst.testNoFail,&nbsp;autoInitTst.testFail,&nbsp;autoInitTst.testTrue,&nbsp;autoInitTst.testFalse (if you have delegates, or the version with F at the end if you have functions).</div><div><br></div><div>TestCollection myTests(TestCollection superColl=null){</div><div><div>&nbsp;&nbsp; &nbsp;TestCollection coll=new TestCollection("myCollection",</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;__LINE__,__FILE__,superColl);</div><div>&nbsp;&nbsp; &nbsp;autoInitTst.testNoFailF("myTest",&nbsp;&amp;myTestFunction,__LINE__,__FILE__,coll);</div><div>&nbsp;&nbsp; &nbsp;...</div><div>&nbsp;&nbsp; &nbsp;return coll;</div><div>}</div><div><br></div><div>and finally small tests can be run in a unittest setup, but for something more serious run them with something like</div><div><br></div><div><div>import blip.rtest.RTest;</div><div>import dchem.test.AllTests: allTests;</div><div>import tango.math.random.Random;</div><div>import blip.io.Console;</div><div>version(NoTrace){} else { import tango.core.stacktrace.TraceExceptions; import blip.util.TraceAll; }</div><div><br></div></div><div><div>void main(char[][] args){</div><div>&nbsp;&nbsp; &nbsp;serr(rand.toString());</div><div>&nbsp;&nbsp; &nbsp;serr("\n");</div><div>&nbsp;&nbsp; &nbsp;mainTestFun(args,allTests!()());</div><div>}</div><div><br></div><div>and this will call the function several times with automatically generated inputs.</div><div>If a function has no arguments it is called just once, if it has only combinatorial arguments then it is not called more often than it should.</div><div>Different tests run in parallel taking advantage of all the cpus you have,and clearly you can write templatized testing functions.</div><div><br></div><div>Blip by default wants blas, lapack and hwlock libraries, but you can compile it without using</div><div>-version=noHwlock -version=noBlas -version=noLapack</div><div>The parallel version stresses a little the thread/fibers and needs a patched version of tango (with the latest reorganizations some bugs crept back, so I use an old version by default, but I hope to submit the patches for trunk soon). Sequential execution can be forced with -version=SequentialWorkManager</div><div><br></div><div>Personally for serious tests I like to recreate the same structure as the module structure, so that x.y.Z has its tests in x.test.y.ZTests , y will contain a collection called YTests that collects all the tests of the modules in the package Y and finally all tests are collected in the AllTests module.</div><div>These functions can even be templates, so that the compilation of the library without tests is fast (my NArray tests are quite extensive and need a bit to compile.</div><div>Then outside the library you have a test runner.</div><div>The test runner has command flags to initialize it with special values (to reproduce a failure), or to ask the execution of a single test or subsets.</div><div><br></div><div>Fawzi</div></div></div></body></html>