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