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