The Artima Developer Community
Sponsored Link

Agile Buzz Forum
A SUnit Extension

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
James Robertson

Posts: 29924
Nickname: jarober61
Registered: Jun, 2003

David Buck, Smalltalker at large
A SUnit Extension Posted: Apr 11, 2004 12:42 PM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by James Robertson.
Original Post: A SUnit Extension
Feed Title: Richard Demers Blog
Feed URL: http://www.cincomsmalltalk.com/rssBlog/rademers-rss.xml
Feed Description: Richard Demers on Smalltalk
Latest Agile Buzz Posts
Latest Agile Buzz Posts by James Robertson
Latest Posts From Richard Demers Blog

Advertisement

A SUnit Extension

Last week I was developing SUnit test cases for code that generates long, deeply-nested XML strings. In the test cases I compared the generated string with a known hand-written string. Great when a test succeeded, but when it failed I had the problem of comparing the strings and finding the discrepancies. I started out using two Inspectors to view the strings, but that quickly became tiresome. Class Store.TextDifferenceBrowser was an easy answer -- just give it two strings and it opens a window that shows you the differences. All I had to do was code my test cases with

Store.TextDifferenceBrowser compare: stringA with: stringB.
self assert: (stringA = stringB).

But of course I didn't really want a comparator window opening every time I ran the test case. My next step was to extend my subclass of TestCase with the following method:

assert: stringA equals: stringB 
 stringA = stringB 
  ifTrue: [self assert: true]
  ifFalse: 
   [Store.TextDifferenceBrowser compare: stringA with: stringB.
   self assert: false]

Now, my test cases could be coded as simply

self assert: stringA equals: stringB.

and the comparator window opens only if the test fails.

But there was still a problem. Test cases can be run in either Run mode or in Debug mode. The main difference is that in Run mode failures are logged and counted as a series of test cases is run, while in Debug mode a debugging window opens at the first failure. So my next problem was to limit the opening of the comparator window to only Debug mode.

A quick scanning of the SUnit source code didn't show me how to distinguish between Run mode and Debug mode, but clearly there was such a distinction. It's great to have source code available to study, but that takes time so I took the easy way out and sent out a query on a Smalltalk mailing list. Michael Lucas-Smith shot right back with the answer. Here it is (with a bit of editing):

We do that in WithStyle so that if a test fails and we ran it in debug, it leaves the window open so we can see why it drew wrongly. If it's not running in debug, the window gets closed no matter what (otherwise, with 500 windows open you tend to run out of system resources ;>)

Here's how we did it:

  1. Add instance variable isDebug to your TestCase subclass, along with a setter method.
  2. Implement #debug to do:
    self resources do: [:res | res isAvailable ifFalse: [^res 
    signalInitializationError]].
    [(self class selector: testSelector) 
    		isDebug: true; 
    		runCase]
        	sunitEnsure: [self resources do: [:each | each reset]]
    
  3. Now you have isDebug set to true whenever you're running in debug mode. A new instance of your test case class is made for each test, so its default value is nil. So also add method:
    isDebug
      ^isDebug == true
    

Here's my modified #assert:equals: method, using the new isDebug TestCase state.

assert: stringA equals: stringB
 stringA = stringB
  ifTrue: [self assert: true]
  ifFalse:
   [self isDebug
    ifTrue: [Store.TextDifferenceBrowser compare: stringA with: stringB].
   self assert: false]

Works great!

Some final thoughts:

  1. VisualWorks Smalltalk (and other versions, too) have a wide range of useful tools readily available to help programmers get the job done -- SUnit and the DifferenceBrowser in this case.
  2. The source for these tools is also available, it can be studied, and it can be modified to meet new needs. There is no need to beg someone to eventually "fix" the language. You can do it yourself.
  3. The Smalltalk community is wonderfully helpful and willing to share ideas, techniques and code.
  4. I'd be willing to bet that Michael's way of distinguishing between Run mode and Debug mode for test cases has many other uses. Maybe it should be integrated into SUnit itself.

Read: A SUnit Extension

Topic: Back home Previous Topic   Next Topic Topic: OT2004 : Taming the Tiger (Java 1.5)

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use