The SenTestingKit Framework


Framework: /Library/Frameworks/SenTestingKit.framework
Header File Directories: /Library/Frameworks/SenTestingKit.framework/Headers

Introduction


Problem

Testing, for instance:

A Solution

Smalltalk Testing Framework, written by KentBeck [1], ported to Java by Gamma [2], ported to Objective C in 1997 by Sen:te.

An Example

You want to test your Set class, or a change you made to it. You can represent predictable reactions in a subclass of SenTestCase. Should is a macro that will raise an exception if its condition parameter is false.

- testAddSet
{
	Set *set = [Set set];
	NSString *string = @"A string";
	NSNumber *number = [NSNumber numberWithInt:5];

	[set addObject: string];
	[set addObject: string];
	[set addObject: number];
		
	should ([set count] == 2);
	shouldnt ([set isEmpty]);
	should ([set containsObject:number]);
}

Now you want to make sure that two sets are equal when their contents are the same.

- testEqualsSet
{
	Set *set = [Set set];
	NSString *string = @"A string";
	NSNumber *number = [NSNumber numberWithInt:5];

	[set addObject: string];
	[set addObject: string];
	[set addObject: number];
		
	shouldBeEqual (set, [Set setWithObjects:number, string, nil]);
}

You notice code duplication for setting up the tests. Testers talk about setting up a test fixture. Just add instance variables to the SenTestCase subclass:

@interface SetTest:SenTestCase
{
	Set *set, otherSet;
	NSString *string;
	NSNumber *number;
}
@end

and initialize the fixture in setUp:

...
- (void) setUp
{
	set = [[Set set] retain];
	string = @"A string";
	number = [[NSNumber numberWithInt:5] retain];
	otherSet = [Set setWithObjects:number, string, nil] retain];
}

- (void) testAdd
{
	[set addObject: string];
	[set addObject: string];
	[set addObject: number];
	should ([set containsObject:number]);
	should ([set count] == 2);
}

- (void) testEquals
{
	[set addObject: string];
	[set addObject: number];
	shouldBeEqual (set, otherSet);
}

- (void) tearDown
{
	[set release];
	[otherSet release];
}

...

You can now run the tests, and exceptions will be raised in case of failures.

	[[SetTest testWithSelector:@selector (testAdd)] run];

If you want to run the tests together, you can create a SenTestSuite:

    suite = [SenTestSuite suiteWithName:@"A suite"];
    [suite addTest:[SetTest testWithSelector:@selector (testAdd)]];
    [suite addTest:[SetTest testWithSelector:@selector (testEquals)]];

    [suite run];

You can also compose suites:

    [suite addTest:myTestSuite];
    [suite addTest:yourTestSuite];

In practice

In practice you only have to write test methods in subclasses of SenTestCase, and let the SenTestingKit take care of everything else. Test suites will be automatically created with your test cases at runtime, and these will be executed.

The Framework

Distinguishes

Implements

Provides


© 1997-2001 Sen:te (Sente SA).