SUnit: Skipping tests?

Markus Gaelli gaelli at emergent.de
Wed Mar 29 17:35:47 UTC 2006


On Mar 29, 2006, at 5:16 PM, Lukas Renggli wrote:

>> I think the block constructs can be used in may cases to achieve the
>> same goal as annotions.
>> Looking at all the should: and shouldnt: construct can give you an  
>> idea.
>>
>> [snip]
>
> I don't understand a single word in your e-mail. What are you talking
> about? What are you using blocks for? What is the purpose of #test:,
> #should:, #shouldnt: ...?

Not a single word. Bummer! ;-)

>
> Can you elaborate what you mean?
Sure. Let me give you three examples.

==Logging==
Let's stick to the canonical example for aspects: Logging.
You could describe this with an annotation "Log this".

But on the other hand you could also wrap the code you want to log  
with a

Bar >> foo
	self log:[body of foo]

construction. Whether your class browser displays you the actual  
source or filters out the log:  could depend on some setting of your  
browser.
If it filters, it could at least provide you with some indicator  
close to the method that logging is on. Yes, I mean it, the possible  
filter options of our class browser for code is highly underestimated  
currently... ;-)

Implementing Object >> log: aBlock
could do all the tricks you need for logging, no?

How would I manage all the aspects? Guess I tried to get away with  
some stupid method category naming convention a la Monticello, as I  
don't know anything better.
Just some method category name with an "aspects" or maybe even aspect  
dependent name like "aspects-loggingOut" or whatever. This is where I  
would store the log: method of course.

Having that in place one could easily iterate over all classes,  
collect the appropriate "aspects" (with all what comes first and last  
problems, one would need a decent tool for that)
and apply them or remove them.

==Tweak Events==
Let me try it with tweak:

MyMorph >> makeYellow
	<on: mouseDown>
	color := Color yellow.

this method should not be called by some other method, but only when  
the mouse is pressed. Another way of tagging this, could be to write  
sth. like

MyMorph >> makeYellow
	self onMouseDown: [color := Color yellow]

and

Object(Tweak-MouseEvents) >> onMouseDown: [aBlock]
	self precondition: [detect if mouse is really pressed].
	^aBlock value

Again, some mechanism could be installed to both put that "aspects"  
in and out of the code, and also manage the mousedown scheduler, to  
call all interested parties when appropriate.

Or just switch it off globally at runtime like a possible solution  
for Object >> assert: aBlock (to be found in our scg VW library)
	Object >> assert: aBlock
		AssertionsOn ifTrue: [aBlock value]

==Testing==
"Unit test" is a funny name, as nobody seems to agree or make  
explicit what the unit under test is.
Having pursued the endeavor of categorizing all unit tests of Squeak  
3.7 we came to the conclusion that most of the tests written in SUnit  
do focus one a single method as unit under test.
This is no wonder as the naming convention of SUnit makes that  
approach natural. (There are certainly others and better ones, the  
best ones I find those, that check, if the inverse function applied  
to the function applied to a parameter delivers the parameter in the  
end.)

All unit tests are decomposable into examples, which focus on single  
methods (I call these guys "method examples"), and tests, which focus  
on single methods. ("method tests").
So method examples and method tests are basically the building blocks  
for our test framework.

It would be nice to navigate between tests and unit under tests,  
which is futile if nobody makes that relationship explicit, and this  
is usually our main job as object-oriented developers.
Romain Robbes did a nice first shot navigating between tests and  
code, but here every method in a test is basically treated to be  
somehow tested/exemplified.

On the other hand some philosophers like Wittgenstein or linguists  
like Lakoff would say that there are better and worse examples for a  
given concept - you would not explain the concept of a bird to a  
child with a penguin first...

So how do I make explicit which "animal" I am really interested in a  
test?

Again, just use the block concept.
	
	FooTest >> testBar
		"Our tool is actually able to detect that this is an InverseTest"
	
		"..someSetupCode for blaBla."
		(...)
		self test: [aResult := blaBla bar inverseBar] "All methods called  
in the test block are methods under test"
		
		"some assertions to make this a test and not a mere example"
		self assert: (aResult = blaBla)
	
Java folks would have to denote the method under test using  
annotations, we don't have to, having our wonderful universal acid of  
lambda calculus.

I hope these three examples clarify my sympathy for using blocks  
instead of annotations more than it confuses, as I bring in my idea  
of examples too. ;-)
Shouldn't have given the examples of should: and shouldnt: as they  
might not have been the best ones.

Cheers,

Markus



More information about the Squeak-dev mailing list