Assert and the optional Message
Jonathan M Davis
jmdavisProg at gmx.com
Fri Mar 9 13:43:56 PST 2012
On Friday, March 09, 2012 22:03:11 Timon Gehr wrote:
> On 03/09/2012 08:29 PM, H. S. Teoh wrote:
> > On Fri, Mar 09, 2012 at 01:37:38PM -0500, Jonathan M Davis wrote:
> >> On Friday, March 09, 2012 09:59:42 H. S. Teoh wrote:
> > [...]
> >
> >>> This opens up the question of, what's the *recommended* way of
> >>> writing unittests that check for these sorts of stuff?
> >>>
> >>> For example, I believe in being thorough in unit tests, so I like to
> >>> use them to verify that the complicated in-contract I just wrote
> >>> actually prevents the erroneous calls that I *think* it prevents.
> >>> But if catching AssertError's may leave the program in an undefined
> >>> state, then that pretty much invalidates any further testing past
> >>> that point (the program may appear to work when compiled with
> >>> -funittest but actually fail in release mode).
> >>
> >> If you're testing that contracts throw when they're supposed to,
> >> you're going to have to be very careful. Depending on what code is
> >> involved, catching the AssertError could have no problems whatsoever.
> >> For example
> >>
> >> assertThrown!AssertError(func(5));
> >>
> >> void func(int i)
> >> in
> >> {
> >>
> >> assert(i == 2);
> >>
> >> }
> >> body
> >> {}
> >>
> >> wouldn't be a problem at all. There are no destructors, scope
> >> statements, or finally blocks involved. But something like
> >>
> >> assertThrown!AssertError(foo(5));
> >>
> >> int foo(int i)
> >> out(result)
> >> {
> >>
> >> assert(result = == 2);
> >>
> >> }
> >> body
> >> {
> >>
> >> Bar bar;
> >>
> >> return i;
> >>
> >> }
> >>
> >> could have issues if Bar has a constructor than needs to run. You just
> >> need to understand that destructors, scope statements, and finally
> >> blocks are not guaranteed to be run if an Error is thrown and avoid
> >> catching Errors in cases where they'd be skipped (or know enough about
> >> the state that the program would be in if they _were_ skipped to know
> >> that it's not going to cause problems).
> >>
> >> Personally, I think that checking contracts is overkill, but you can
> >> do it if you're careful.
> >
> > [...]
> >
> > Hmph. Well, then that defeats the purpose of checking contracts, because
> > checking contracts is only justifiable if it's complex enough, which
> > means that it's liable to involve things like dtors and scope
> > statements. It's silly to want to check a trivial contract like
> > assert(x>0);, because if something *that* simple can go wrong, then so
> > can the unittest, so you're not proving anything at all.
> >
> > But this isn't that big a deal. One could argue that if a contract is
> > convoluted enough to warrant a unit test, then perhaps most (or all) of
> > its complexity should be factored out into a separate, unit tested
> > function, which is then just invoked from the contract.
> >
> > (I find this a bit ironic, since TDPL states that the reason contracts
> > allow statements is so that complicated conditions can be tested for,
> > rather than being limited to just a single expression, as is the case in
> > most other languages that support DbC. Now it seems that simple
> > contracts are the way to go.)
> >
> >
> > T
>
> Jonathan is just speculating. And I think he is wrong.
Speculating about what?
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list