Test first, develop later! That’s the greeting when you visit OCUnit, similar to JUnit. Note that for this tutorial, you do not need to install OCUnit as it comes “built-in” in XCode as of v2.1.

  1. Create a new iPhone Window-based application project “SampleTest”.

  2. Our subject for testing is Converter.m which converts kilometers to meters. Let’s implement an incorrect conversion by specifying 1km = 100 meters (should be 1000 meters) so we can see that the unit test captures it below…

#import "Converter.h"
 
@implementation Converter
 
- (id)init{
	if(self = [super init]){
 
	}
	return self;
}
 
- (int)convertKilometersToMeters:(int)km{
	return km * 100;
}
 
@end
  1. Add another target “UnitTests”. Right click on Targets -> Add -> New Target… -> Choose Unit Test Bundle.

unit-test-bundle.png

  1. Name it “UnitTests”. After hitting submit, you will be presented with the project settings for “UnitTests”.

unit-test-name2.png

  1. Go to the General Tab -> Click on the “+” icon above “Linked Libraries”. Choose “SampleTest” as the application we have direct dependency with.

unit-test-dependency-3.png

  1. Close the Settings. To check, navigate under “Groups & Files” -> Targets. You should see the SampleTest Application Icon just below “UnitTests”.

unit-test-tree-4.png

  1. Right Click on “Sample Test” -> Add -> New File…

unit-test-class5.png

  1. Name the file “ConverterTest. Don’t forget to also create the header file (default). Specify it also in a different directory under “Location”. Then check the UnitTests as the “Targets”. When you hit “Finish” it will ask you to create the folder “Tests”

unit-test-class6.png

Tip: Keep things organize and put it under a “Tests” Group. Right Click on “Sample Test” -> Add -> New Group… Name it “Tests”, then drag the files (ConverterTest.h and ConverterTest.m) into that group.

  1. Open up ConverterTest.h and notice that “SenTestingKit.h” is already imported. Now let’s add method testKilometersToMeters as shown below. Test methods usually start out with a test prefix.

In the implementation, let’s import Converter.h and use STAssertTrue. To test the convertKilometersToMeters method, we are asserting that the result should be 1000. If not, then we should know! That is why we are writing a unit test for.. making sure that our implementation doesn’t break.

#import "ConverterTest.h"
#import "Converter.h"
 
@implementation ConverterTest
 
- (void)testKilometersToMeters{
	int km = 1;
	Converter *converter = [[Converter alloc] init];
	int meters = [converter convertKilometersToMeters:km];
	STAssertTrue(meters == 1000, @"converting %d km to meters should equal 1000, instead received %d", km, meters);
}
 
@end
  1. Now, before we build our target “UnitTests”, we need to include additional class references from our application. Drag Converter.m to the “Compile Sources” under UnitTests.

unit-test-drag7.png

  1. Now we can build. There are many ways to do this. My preference is to do a clean build when testing. Right Click on Sample Test then choose “Clean SampleTest”. Afterwards choose “Build SampleTest”.

unit-test-build8.png

If you have a succesful build for SampleTest, lets do the same for our “UnitTests”.

unit-test-build9.png

  1. Here’s the crux of it. Notice the error in your “Build Results”?
/Users/rupert/projects/iphone/SampleTest/Tests/ConverterTest.m:18: error: -[ConverterTest testKilometersToMeters] : "meters == 1000" should be true. converting 1 km to meters should equal 1000, instead received 100

unit-test-results.png

Now changing the correct implementation of convertKilometersToMeters will put the error away and you will have a successful build.

- (int)convertKilometersToMeters:(int)km{
	return km * 1000;
}
  1. Look up the assert methods from SenTest.h.
#import <Foundation/NSObject.h>
#import "SenTest.h"
 
#define STAssertNil(a1, description, ...)
#define STAssertNotNil(a1, description, ...)
#define STAssertTrue(expression, description, ...)
#define STAssertFalse(expression, description, ...)
#define STAssertEqualObjects(a1, a2, description, ...)
#define STAssertEquals(a1, a2, description, ...)
#define STAssertEqualsWithAccuracy(left, right, accuracy, description, ...)
#define STAssertFalseNoThrow(expression, description, ...)
....

References:

http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/UnitTesting/Articles/CreatingTests.html

http://developer.apple.com/tools/unittest.html

Download: SampleTest.zip