What's up with the assert enhancements proposed years ago?

Nick Sabalausky via Digitalmars-d digitalmars-d at puremagic.com
Sat Sep 24 06:50:16 PDT 2016


On 09/24/2016 03:34 AM, Jonathan M Davis via Digitalmars-d wrote:
> On Friday, September 23, 2016 23:50:03 Nick Sabalausky via Digitalmars-d
> wrote:
>>
>> And then that leads too, to the question of whether such third-party
>> asserts are a good idea for the doc unittests I like so much... :/
>
> I'd say not. If you're writing a library for general consumption, I don't
> think that anyone else who is not actually helping to develop it should have
> to know or care what unit testing facilities you're using. assert is
> universal and clear, whereas other stuff is not universal and may or may not
> be clear to those not familiar with it.
>

Yea, honestly, that's my thought as well. :(  And it's a big part of why 
I was (and still am) so disappointed that assertPred didn't become 
official even if it is technically usable as third-party. We could've 
already been using that for years by now, standard, if it weren't for 
D's habit of letting perfect be the enemy of progress.

> Also, my take on it is that ddoc-ed unittest blocks are really there to just
> give examples for the documentation, not to test your code. You want the
> examples tested so that you know that they work - which is why ddoc-ed
> unittest blocks are such a great feature - but it's not their purpose to
> test your library. It would be wholly unreasonable to have thorough tests in
> the documentation, and what makes a good example doesn't necessarily make
> for a very good test (or vice versa).
>

I think there's a balance (albeit a difficult one). I agree that being 
pedantic with the examples can make them overly cluttered, so that 
should be avoided. But all major side-cases should still be documented, 
and examples help with that as they do with anything else.

For example, std.path.buildNormalizedPath: It should not only document 
typical cases like `buildNormalizedPath("foo","bar")`, but it's very 
important for its docs to also be clear about various other significant 
cases:

- How does it handle empty strings as arguments?
- What does it return for buildNormalizedPath("foo",".."). It used to 
return empty string which turned out very problematic. Now it returns 
"." which is much better.
- What happens when I do buildNormalizedPath(relativePath,absolutePath)?

These are all very important cases that still need to be documented. And 
examples work excellently as documentation here. (And IIRC, 
buildNormalizedPath docs are doing a good job of this.)

So a good set of examples *do* still test a significant amount of a 
function, even if it isn't exhaustive.

So because of that, and heck, even if your examples *are* overly sparse, 
sometimes you will get a failure in one. Which, of course, is the whole 
point of actually testing them. And when you do, it's a big help for the 
diagnostic output to actually be, well, helpful:

The whole cycle of:

- Search the stack trace for the relevant file/line number.

- Find it:
assert(x.foo(blah...) == y);

- Insert scaffolding:
import std.stdio;
writeln("x.foo(blah...): ", x.foo(blah...));
writeln("y: ", y);

- Recompile/re-run tests (and maybe go back again and fix any stupid 
typos in the scaffolding).

- Finally view key information that COULD'VE been shown right from the 
start.

Gets very tiresome very quickly, even if it's only in the example tests.



More information about the Digitalmars-d mailing list