[squeak-dev] Re: Specifying with a TestCase
nicolas cellier
ncellier at ifrance.com
Thu Sep 25 23:34:13 UTC 2008
HeHe, forgot the declaration of temps:
| finalizationProbe o1 o2
forAnyTwoEqualObjects
ofDifferentIdentity
registeringAnActionAtFinalizationForEachObject
thenForcingFinalizationOfObjects
implyBothRegisteredActionsAreExecuted |
are Worth a method comment!
nicolas cellier a écrit :
> I want to relate here a discussion taking place at
> http://bugs.squeak.org/view.php?id=6347
> Thanks to Norbert Hartl for his collaboration and time devoted to it.
>
> The subject is how to write a system specification TestCase.
> The example taken from the bug report is to clearly express this rule:
>
> "For every pair (o1,o2) of equal objects (o1=o2),
> of different identity (o1~~o2),
> registering an action for each object of the pair at finalization,
> shall trigger both actions upon finalization."
>
> I put here a new attempt with self documenting code:
>
> finalizationProbe := Set new.
> o1 := 'hello' copy.
> o2 := 'hello' copy.
> forAnyTwoEqualObjects := [o1 = o2].
> ofDifferentIdentity := [o1 ~~ o2].
> registeringAnActionAtFinalizationForEachObject := [
> o1 toFinalizeSend: #add: to: finalizationProbe
> with: 'first hello finalized'.
> o2 toFinalizeSend: #add: to: finalizationProbe
> with: 'second hello finalized'].
> thenForcingFinalizationOfObjects := [
> o1 := o2 := nil. Smalltalk garbageCollect].
> implyBothRegisteredActionsAreExecuted := [finalizationProbe size = 2].
>
> self
> assert: forAnyTwoEqualObjects;
> assert: ofDifferentIdentity;
> should: [
> registeringAnActionAtFinalizationForEachObject value.
> thenForcingFinalizationOfObjects value.
> implyBothRegisteredActionsAreExecuted value].
>
> Preamble longer than pure English, and the #value are a bit parasitic...
> And why using leading assertions? They are not the goal of the test...
>
> Well, the TestCase don't prove the implication by itself.
> It just tells whether verified or not for some objects.
>
> Assertions are there to clearly states that the rule is not meant to be
> casually true for some objects, but shall apply to any objects verifying
> the pre-condition.
> They are the left member of the implication we want to verify.
> They are also self-protecting the TestCase (if ever the two objects
> chosen become identical or not equal after a refactoring).
> I think they have their place here.
>
> Trusting the comments does work as well and leads to a shorter code:
>
> "For every pair of equal objects of different identity,"
> o1 := 'hello' copy.
> o2 := 'hello' copy.
> "when both are registering an action at finalization,"
> finalizationProbe := Set new.
> o1 toFinalizeSend: #add: to: finalizationProbe
> with: 'first hello finalized'.
> o2 toFinalizeSend: #add: to: finalizationProbe
> with: 'second hello finalized'.
> self assert: finalizationProbe size = 0.
> "upon finalization..."
> o1 := o2 := nil. Smalltalk garbageCollect
> "...both actions shall be triggered"
> self assert: finalizationProbe size = 2.
>
> Or see excellent variation from Norbert with a pair. Small is beautiful.
> But notions of equal objects (o1 = o2) and different identity (o1 ~~ o2)
> are very much implicit here.
> Good for readability, but is it a clear rationale for using
> IdentityDictionary?
>
> Sure, the whole discussion is overkill!
> Regarding productivity, including time to discuss how to write tests,
> rules shall better not change too fast! Reserved to a stable Kernel...
> Or a Smalltalk academy rewriting the Kernel every 100 years or so.
> I wonder if we can specify a whole Smalltalk Kernel like this by the
> way? (If we cannot specify a method, then throw it away!).
>
> I wish this example serve as a mirror to reflect our own practices.
> Do we really write TestCase with specifications in mind?
> Can they serve as a rationale for an implementation?
> Which readers are the TestCase addressed to?
> Not sure i can understand every TestCase intention in the image...
> Shouldn't I?
>
> Nicolas
>
>
>
More information about the Squeak-dev
mailing list
|