Removing ddoc and unittest

Christopher Wright dhasenan at gmail.com
Mon Nov 10 17:30:02 PST 2008


bearophile wrote:
> Walter Bright:
> 
>> Experience has led me to believe that unit tests are extremely valuable, but I rarely see them used - even by professionals.<
> 
> In languages with dynamic typing (Python, Ruby, etc) they are used quite often, partially to replace errors that the static typing catches, and partially for other purposes (but after writing about 110.000 lines of D code I have seen that unit tests result very useful in D code too).
> In dynamic languages they have even invented a programming style (TDD, Test-Driven Development) that is strictly based on unit tests: you write a unit test first, see it fail, you fix the code to make it pass, you add another unit test, you add a little more code, you see it fail, etc etc. I know it sounds a little crazy, but if you use dynamic languages to write certain classes of programs (surely it's not fit for every kind of code) it seem to work well enough (for some kinds of programmers, I presume).
> 
> 
>> I wanted to make them so easy to use in D that it would hook people in. That's why they are the way they are - super simple, next to nothing to learn, and they work.<
> 
> I understand. The profilers you are talking about push too much complexity to the final user. But ergonomics shows there are other possible designs for the interfaces of tools: sometimes you can push some more complexity into the product even if its interface is kept simple enough, making it flexible only where it more counts. So I think there are "few things" that can be added to the current unit test system that can increase its usefulness and make it more handy while keeping a simple user interface.
> 
> It's not easy to find and list such few things, I can try list something:
> 
> 1) I'd like a way to state that an expression throws one or more specified exception(s), at runtime, for example:
> Throws!(ArgumentException)(foo("hello", -5));
> It also has to print that line number of the caller.
> I have created something similar, but it's quite less nice:
> assert( Throws!(ArgumentException)(foo("hello", -5)) );
> See my Throws!() here:
> http://www.fantascienza.net/leonardo/so/dlibs/func.html

For what it's worth, dunit supports this:

tests["no expected exception"] = {};
tests["fails if it doesn't throw"] = expectedException!(AssertError) = { 
assert(false); };

I was attempting to channel downs when I came up with this syntax.

> 2) The same at compile time. I think it's impossible to do currently:
> static Throws!(AssertError)(foo(5, -5));
> 
> 3) I need ways to unittest a specified module only. And I'd like to be able to do it even if the main is missing. Having a compiler-managed "mainmodule" boolean constant that is true only in the main module may help.

Dunit also supports unittesting a single module, but since it replaces 
main, you can't do without it. That said, I'm looking for workarounds, 
such as outputting a module sufficient to compile and run tests in the 
given paths.

> 4) I'd like to unittest nested functions too.

That's not going to be easy.

> 5) Few reflective capabilities can be added to D to help the handy creation of an external unittest system, for the people that need something quite more refined and complex.

d2 will get some improvements that I really would like for dunit. 
Runtime reflection to get a callable list of the methods on a class is a 
big one -- the current syntax is a hack. But that won't be sufficient to 
move to an Nunit/Junit style syntax; you won't get filters 
(parameterized tests, expected exceptions, and the like).

The really big thing after runtime reflection is user-defined metadata 
-- attributes or annotations, in C# or Java. User-defined metadata has a 
lot of other use cases, so I'm hoping this makes it into the language 
within a reasonable amount of time.

> --------------------------
> 
> I have already given two times links to the wonderful doctest system of Python, but it seems no one has read it, I have seen no one comment on it. So I try a third time, this time I explain a little more.
> 
> Note that doctests are unfit for the current D language, but if D gains some runtime capabilities (like I have seen shown here two times), then its phylosophy may become usable.
> 
> Note that I am not talking about Test-Driven Development here, this is "normal" way of coding.
> 
> 
> This is a little useful Python function that returns true if the given iterable contains items that are all equal. If given an optional mapping function is used to transform items before comparing them:

This is interesting. It's not as flexible as dunit or D's unittest 
blocks -- it'll complain about any user-visible changes to a function. 
It also looks like it'd be annoying to use, say, mock objects with it.

I would have no use for doctests, but I think it's a neat hack.



More information about the Digitalmars-d mailing list