Assert and the optional Message

Timon Gehr timon.gehr at gmx.ch
Fri Mar 9 13:03:11 PST 2012


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.


More information about the Digitalmars-d-learn mailing list