www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - CTFE unit tests

reply Jacob Carlborg <doob me.com> writes:
Recently I added a new trait to get all the unit tests functions from a 
module. With this in place, among other things, it's possible to do unit 
tests for CTFE functions. Here's a quick try:

http://pastebin.com/Kk0in3bD

What's missing is CTFE-able "writeln".

It's also possible to implement named unit tests in library code, now 
when it's possible to access UDA's from the unit test functions.

-- 
/Jacob Carlborg
Jul 15 2013
parent reply Timothee Cour <thelastmammoth gmail.com> writes:
On Mon, Jul 15, 2013 at 10:34 AM, Jacob Carlborg <doob me.com> wrote:

 Recently I added a new trait to get all the unit tests functions from a
 module. With this in place, among other things, it's possible to do unit
 tests for CTFE functions. Here's a quick try:

 http://pastebin.com/Kk0in3bD

 great, thanks

 What's missing is CTFE-able "writeln".

awaiting https://github.com/D-Programming-Language/dmd/pull/692 or CTFE exec
 It's also possible to implement named unit tests in library code, now when
 it's possible to access UDA's from the unit test functions.

I would still prefer the short and sweet syntax: unittest(myunittestname){...} rather than the cumbersome: named("myunittestname") unittest{...} These named unittests would ideally be referable to inside DDOC (as opposed to current horrible practice of duplicating examples inside documentation, which are never in sync) Later, for a more complete testing infrastructure, we would need additional attributes indicating for example whether the unittest is near-instantaneous or takes a long time to run (to filter out slow ones when needed)
Jul 15 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 15 July 2013 at 20:50:59 UTC, Timothee Cour wrote:
 These named unittests would ideally be referable to inside DDOC 
 (as opposed
 to current horrible practice of duplicating examples inside 
 documentation,
 which are never in sync)

http://dlang.org/changelog.html#documentedunittest
Jul 15 2013
next sibling parent Timothee Cour <thelastmammoth gmail.com> writes:
On Mon, Jul 15, 2013 at 2:07 PM, Dicebot <public dicebot.lv> wrote:

 On Monday, 15 July 2013 at 20:50:59 UTC, Timothee Cour wrote:

 These named unittests would ideally be referable to inside DDOC (as
 opposed
 to current horrible practice of duplicating examples inside documentation,
 which are never in sync)

http://dlang.org/changelog.**html#documentedunittest<http://dlang.org/changelog.html#documentedunittest>

Thanks, forgot it appeared in 2.063. Now the feature just needs to be used ! (so many out of date examples embedded in documentation at the moment).
Jul 15 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Jul 15, 2013 at 02:20:06PM -0700, Timothee Cour wrote:
 On Mon, Jul 15, 2013 at 2:07 PM, Dicebot <public dicebot.lv> wrote:
 
 On Monday, 15 July 2013 at 20:50:59 UTC, Timothee Cour wrote:

 These named unittests would ideally be referable to inside DDOC (as
 opposed
 to current horrible practice of duplicating examples inside documentation,
 which are never in sync)

http://dlang.org/changelog.**html#documentedunittest<http://dlang.org/changelog.html#documentedunittest>

Thanks, forgot it appeared in 2.063. Now the feature just needs to be used ! (so many out of date examples embedded in documentation at the moment).

One problem with these ddoc-unittest, though, is that you still have some issues when writing ddocs for templated structs/classes. For example: struct MyStruct(T) { /// Docs for MyMethod void MyMethod(...) { ... } /// ddoc-unittest unittest { MyStruct!int exampleStruct; ... } } The problem is that your unittest will be instantiated for every type T that you instantiate MyStruct with, even though the resulting code is identical (it's generally a good idea to explicitly write, e.g., MyStruct!int in ddoc unittests, since you want users to see a concrete example, not something involving T implicitly or explicitly). This wastes memory when compiling, and increases program startup time by running redundant tests. One workaround is to use static if to restrict the instantiation of the unittest: struct MyStruct(T) { /// Docs for MyMethod void MyMethod(...) { ... } static if (is(T == int)) { /// ddoc-unittest unittest { MyStruct!int exampleStruct; ... } } } // Force instantiation of MyStruct!int so that unittest will // actually get instantiated once! // // Problem: if you forget to do this, your unittest may never // actually be compiled, so it doesn't actually run. version(unittest) MyStruct!int _dummy; This isn't ideal, since there's possibility of bugs if you forget that last part to instantiate MyStruct!int: your unittest will never actually run. Plus, it's a hassle to keep typing out these static ifs. T -- In order to understand recursion you must first understand recursion.
Jul 15 2013