[phobos] Silent failure of std.container unittests
Steve Schveighoffer
schveiguy at yahoo.com
Fri Jul 16 07:31:42 PDT 2010
----- Original Message ----
> From: Walter Bright <walter at digitalmars.com>
> To: Discuss the phobos library for D <phobos at puremagic.com>
> Sent: Thu, July 15, 2010 7:11:28 PM
> Subject: Re: [phobos] Silent failure of std.container unittests
>
>
>
> Sean Kelly wrote:
> > On Jul 15, 2010, at 3:00 PM, Walter Bright wrote:
> >
> >>> NOT YET:
> >>>
> >>> 4. DESIRED: assert is NOT hacked, any failing assert ends the current
>unittest, the failure message is printed, execution continues with the next
>unittest, program ends with error code if at least one assert failed,
>everybody's happy.
> >>>
> >>>
> >> Everybody's happy except the guys like me who want to run all the unit
>tests in one go.
> >>
> >
> > All the unit tests or all the asserts?
>
> All the asserts.
>
> > All the unit tests are run with this approach:
> >
> > module A;
> >
> > unittest {
> > assert(false, "test 1a failed");
> > assert(false, "test 1b failed");
> > }
> >
> > unittest {
> > assert(false, "test 2 failed");
> > }
> >
> > This should print:
> >
> > test 1a failed
> > test 2 failed
> >
> > I'm not sure I understand the problem of breaking unit tests into a
>collection of atomic blocks.
>
> Extra work.
But then assert doesn't do what assert is supposed to do.
The problem I see here is, inside unit tests, assert means two different things:
1. Display an error if a value isn't what it's supposed to be.
2. Make sure my code is in a sane state before it goes any further.
During unit tests, assert is used for 1 mostly, but many use it for 1 and 2
combined.
A sample from dcollections, with each assert marked as whether it is 1 and/or 2:
static if(doUnittest) unittest
{
auto hs = new HashSet;
hs.add([1, 2, 3, 4, 5]);
auto r = hs[];
assert(rangeEqual(r, cast(V[])[1, 2, 3, 4, 5])); // 1, 2
assert(r.front == hs.begin.front); // 1
assert(r.back != r.front); // 1
auto oldfront = r.front;
auto oldback = r.back;
r.popFront();
r.popBack();
assert(r.front != r.back); // 1, 2
assert(r.front != oldfront); // 1, 2
assert(r.back != oldback); // 1, 2
auto b = r.begin;
assert(!b.empty); // 1
assert(b.front == r.front); // 1
auto e = r.end;
assert(e.empty); // 1
}
I'm almost thinking we need to dump assert as "the way to fail unit tests" and
go with something more configurable. Leave assert the way it is.
Then, what we need is two functions, one that "exits the current unit test", and
one that "just prints out a failure".
I'd suggest require() and check().
Note that we do not need the special traits of assert, it should only be used
during unit tests.
FWIW, the current mode of unit testing (assert doesn't throw) didn't hinder much
the testing of dcollections.
-Steve
More information about the phobos
mailing list