Help with SUnit

John M McIntosh johnmci at smalltalkconsulting.com
Thu Jan 22 18:20:02 UTC 2004


When I attempt this with a 3.7a image and at change set 5566  I first  
use the open menu to open a Test Runner 'SUnit Camp Smalltalk 3.1 Test  
runner; which shows my JMMTestCase, which I select, then I click on the  
RUN button I get my JMMTestCase failed, I click on the failing method,  
I get a notifier up that when I debug I see

openDebuggerOnFailingTestMethod
	"SUnit has halted one step in front of the failing test method. Step  
over the 'self halt' and
	 send into 'self perform: testSelector' to see the failure from the  
beginning"

I then proceed and I get TestFailure: Assertion failed
with this on the stack

assert: aBoolean
	aBoolean ifFalse: [self signalFailure: 'Assertion failed']

If I click down to the  testMe method I see the instance variables are
testSelector: 	#testMe
stream: 	a WriteStream
	

I'm not sure which image or SUnit version you are using, you might want  
to try with 3.7a and see what happens since I was unable to reproduce  
your results.

Also if I might comment on your
> tearDown
> 	stream _ nil
which technically performs the destruction of the WriteStream instance.  
Sometimes folks coming from the C/C++ world feel they must explicitly  
destroy all variables after usage, this isn't required in GC languages  
since the variable will get reclaimed once it's no longer accessible.  
In this case the WriteStream instance goes away either when the  
instance of your TestCase is forgotten, or in setUp when we reassign  
what the instance variable stream is referring to. Although this is a  
minor issue I have seen smalltalk systems where dozens of instance  
variables are set to null and attempts made to call each of them to  
cleanup things, when a domain object is 'deleted' That results in lots  
of cycles taken up doing needless work.

Explicit deletion can led to bugs, however I'll temper that with the  
comment that some objects might need closure if they don't have Weak  
Reference support to ensure system resources are surrendered at GC  
time, or if the frameworks involved don't forget about them  
automatically at some point.

In this case the stream _ nil isn't needed. However if it was a file  
based stream then a close should be done, mind you weak reference  
support would ensure the file is closed automatically when the stream  
was actually GCed even if you didn't do an explicit close.

> self halt in tearDown (feeling on dodgy ground now)

Please feel free to do that anywhere, why else would Smalltalkers ship  
all the source other than so you can read/learn/fiddle, older  
smalltalkers might recall (with distaste) when Digitalk and IBM hid  
source code from us. Mind sticking a self halt anywhere can lead to  
disaster, but it's a learning experience.

On Jan 22, 2004, at 9:27 AM, Michael Roberts wrote:

> I've got myself a bit confused with SUnit and was hoping someone might  
> be able to help out.  This feels like a bug but much of the time I  
> just need to learn some more Squeak!  I feel desperately stupid  
> because I can't find what I'm doing wrong!
>
> I have a test class with one instance variable 'stream'.  I have  
> attached the file but it is easy enough to walk through its three  
> methods.
>
> setUp
> 	stream _ WriteStream on: ''
>
> tearDown
> 	stream _ nil
>
> testMe
> 	self assert: stream notNil.
> 	stream nextPutAll: 'I have a cunning plan'.
> 	self assert: false
>
> The thing that is confusing me is this:
> 1) the test should fail on the last line.  You can set this to true to  
> check it passes.
>
> 2) SUnit brings up a debugger on the failing test but stream is nil so  
> you can't get past the first line.  I have started to walk through  
> this code and below is my idea so far...
>
> TestCase>>runAsFailure: does a self setUp followed by self  
> openDebuggerOnFailingTestMethod which in turn runs the test in its own  
> process and attaches the debugger.
>
> 3) When the debugger runs, however, stream is nil as illustrated by  
> the position of the debugger highlight and checking the object's  
> state.  I'm guessing that somewhere the test execution is stopped at  
> the first error. this isn't the line that caused the assertion though.
>
> If I put some self halts into SUnit (probably a bad idea, I eventually  
> get code simulation errors etc) I can run through the original  
> execution of the test to see that it asserts on the last line.  I can  
> then watch the failed test get setup correctly and see a valid stream  
> instance variable.
>
> 4) I get a valid instance variable by stepping into  
> openDebuggerOnFailingTestMethod but can't go any further.
>
> 5) If I put a self halt in tearDown (feeling on dodgy ground now)  
> something is sending tearDown to the test the instance after the  
> debugger is opened on the failing test. I can then confirm that the  
> test instance is now not valid.
>
> 6) If I look at the stack of what is sending tearDown it's coming from  
> here
>
> runCaseAsFailure: aSemaphore
> 	[self setUp.
> 	self openDebuggerOnFailingTestMethod] sunitEnsure: [
> 		self tearDown.
> 		aSemaphore signal]
>
> which should be the same place that opened the debugger earlier.
>
> 7) how does the block to sunitEnsure: wait for  
> openDebuggerOnFailingTestMethod to finish?  It should just be a normal  
> block being sent >>value.
>
> If openDebuggerOnFailingTestMethod waits until the debugger is closed  
> then the ensure block shouldn't get called.  If  
> openDebuggerOnFailingTestMethod doesn't stop then the test instance  
> gets clobbered by the ensure block?
>
> I'm a bit lost in this method!
>
> 8) surely I'm doing something daft right? :-)
>
> Cheers
> Mike
>
>
> <MikeIsConfusedTest.st>
>
--
======================================================================== 
===
John M. McIntosh <johnmci at smalltalkconsulting.com> 1-800-477-2659
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
======================================================================== 
===




More information about the Squeak-dev mailing list