The mother of all unit testing frameworks


SUnit Update

The SUnit project is moving again with 3 new releases in the last year. Project releases are now placed in the public repositories for the relevant dialects (i.e. the Cincom Open Repository, the VastGoodies site, etc.) wherever these exist, being stored here only where the dialect lacks a sufficiently well-known one.

SUnit 4.0, 3.3 and 3.2 changes from 3.1

SUnit 4.0

TestResult now double-dispatches via the exception (see #sunitAnnounce:toResult:). This makes it easier for users to plugin specific behaviour.

TestResource #setUp and #tearDown is now consistent with TestCase #setUp and #tearDown. TestResource>>setUp is _not_ called by TestResource>>initialize; the framework calls TestResource>>setUp separately. If TestResource>>setUp is entered then a call of TestResource>>tearDown is ensured, just as for TestCase. (TestResource>>uninitialize, introduced in in SUnit 3.2 in an earlier attempt to address this problem, is now deleted.)

IMPORTANT: it has always been the case that TestCase>>tearDown code may require

	someVar isNil or: [someVar doTearDownStuff].
guards to handle the possibility that the test fails in early #setUp before someVar has been assigned (the symptom of not having the guard is that the run shows two errors for the same test in that case). The above change to TestResult means that some resource #tearDown code may now also require these guards. These cases are usually very obvious to spot and fix, so we have accepted this side effect of the change.

Otherwise, framework behaviour and API are unaffected by this change. However in the very rare case that a user has written a programmatic script for manipulating TestResources, they would need to replace any

	var := MyTestResource new.


	var := MyTestResource new; setUp.

since #new's call of #initialize no longer calls #setUp.

There are changes to #testSelectors, #allTestSelectors, #sunitAllSelectors (which is now deprecated) and #sunitSelectors (which is now in protocol 'private', does not guarantee order, is now trivial to inline and may in future be deprecated). Associated changes to #buildSuiteFromSelectors, with deletion of #buildSuiteFromLocal/AllSelectors, integrate suite building with #shouldInheritSelectors and a new method, #lookupHierarchyRoot, giving more consistent test inheritance behaviour, and better performance in hierarchies with many selectors and fewer test selectors. Any utilities that called #buildSuiteFromLocal/AllSelectors explicitly can eliminate both calls, and the boolean test that decides which call to send, in favour just calling #buildSuiteFromSelectors.

In all normal-usage cases, TestResources now ask their requesting test or candidate-resource to signal their failure, thus providing more informative logging.

SUnit 3.3

It introduced the method TestResource class>>resetResources: to ensure safe ordering of resource tearDown in edge cases where multiple resources used by a suite could share dependency on a resource.

SUnit 3.2

It made the order of TestResource tearDown be the reverse of the order of TestResource setUp. It made resource setUp lazy: the first test in a suite that requires a given resource attempts to set it up and the result of the attempt applies throughout that run of the suite. Thus tests that do not require a failed-setUp resource still run, rather than the whole suite aborting.

It introduced TestAsserter, a common superclass of TestResource and TestCase that assists refactoring of code from one to the other (and also provides a suitable superclass for any TestCase delegate classes users may create).

It made minor method category changes for consistency.

SUnit 3.1 changes from earlier versions

What's new in SUnit 3.1

SUnit 3.1 includes a various bug fixes, as well as a small number of additions and extensions to SUnit. The reason for the release's delay has been the lack of time available to devote to the project, and the problems associated with creating a clean, dialect-independent code base.

SUnit Camp Smalltalk is still available in four parts:

This is a list of the changes made to each module.


SUnit Core

The SUnit core package has achieved the goal of having the exact same code for all dialects - almost. The only dialect using a variant code base is Object Studio. Other than that, the changes consist of additions and bug fixes.


1. Assertion description strings

The TestCase assertion protocol has been extended with a number of methods allowing the assertion to have a description.. These methods take a String as second argument. If the test case fails, this string will be passed along to the exception handler, allowing more variety in messages than "Assertion failed" gives you. Of course, this string can be constructed dynamically.

    | e |
    e := 42.
    self assert: e = 23 description: 'expected 23, got ' e printString

The added methods in TestCase are:

2. Logging support

The description strings described above may also be logged to a Stream such as the Transcript, a file, stdout etc. You can choose whether to log by overriding TestCase>>#isLogging in your test case class, and choose where to log to by overriding TestCase>>#failureLog.

3. ResumableTestFailure

A resumable TestFailure has been added. What can this be used for? Take a look at this example:

aCollection do: [ :each | self assert: each isFoo]

In this case, as soon as the first element of the collection isn't Foo, the test stops. In most cases, however, we would like to continue, and see both how many elements and which elements aren't Foo. It would also be nice to log this information. You can do this in this way:

aCollection do: [ :each |
          assert: each isFoo
          description: each printString, 'is not Foo'
          resumable: true]

This will print out a message to your logging device for each element that fails. It doesn't cumulate failures, i.e., if the assertion fail 10 times in your test method, you'll still only see one failure.

Bug fixes


SUnitUI Logo