
When the original iPhone SDK was released it lacked unit testing capabilities. Third-party solutions were adapted or created to fill the gap. However, in the interim, with the 2.2 version of the SDK, Apple has quietly brought back the OCUnit unit test solution.
One of the biggest advantages of Apple’s OCUnit implementation is the tight integration into Xcode. This means you get IDE errors instead of having to parse the console output.
Using OCUnit
Starting with an existing Xcode iPhone project:
-
Add a new Unit Test bundle target using the Project > New Target… menu items. Select Unit Test Bundle under the Cocoa grouping in the Mac OS-X section.

-
Modify the “Other Linker Flags” setting:
We need to change the
Cocoavalue toFoundation. This will allow us to compile for the iPhone Simlulator
Lastly, search for any Cocoa.h references and delete them:

-
Add a test file with a TestCase subclass in it:
Using the Mac OS X > Cocoa > Unit Test Case Class template, create and add a new test case file.
Test Case files must end in
TestCase(e.g., MathTestCase or BackEndTestCase). Similarly, all test methods should start withtest. The underlying test mechanism uses some very nifty runtime magic to determine which classes and methods to run based on their names.
Make sure you are only adding to the Unit Test Bundle and not to the main project:

-
Add a test:
Here’s a easy one you can use to test the test framework itself.
- (void)testTestFramework { NSString *string1 = @"test"; NSString *string2 = @"test"; STAssertEquals(string1, string2, @"FAILURE"); NSUInteger uint_1 = 4; NSUInteger uint_2 = 4; STAssertEquals(uint_1, uint_2, @"FAILURE"); } -
Build the test bundle; make sure tests pass.
-
Build the test bundle; make sure tests fail:
Again, just to exercise your test framework, temporarily change one of the strings to force a test failure.

-
Add the unit test bundle as a dependency:
Now, we want the unit tests to run every time we build. We can do this by setting a dependency on the Unit Test Bundle. Switch back to the main project target (away from the unit test bundle) and Edit the Active Target. Click the + button under to add and new
Direct Dependancy.
Now you have an automated testing framework in place. Every time you build, you will be immediately notified of any test failures.
For a complete, working example download this sample project.
An Eesthetic Note About Header Files
Test Case files header files are nearly always empty, so I usually get rid of them, creating single file test cases. The resulting .m looks like this:
//only run on the simulator
#include "TargetConditionals.h"
#if !TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#import <SenTestingKit/SenTestingKit.h>
@interface SampleTestCase : SenTestCase
{
}
@end
@implementation SampleTestCase
- (void) setUp
{
// Optional
}
- (void) tearDown
{
// Optional
}
- (void)testTestFramework
{
NSString *string1 = @"test";
NSString *string2 = @"test";
STAssertEqualObjects(string1,
string2,
@"FAILURE");
NSUInteger uint_1 = 4;
NSUInteger uint_2 = 4;
STAssertEquals(uint_1,
uint_2,
@"FAILURE");
}
@end
#endif
Alternatives
Other iPhone based testing frameworks and utilities:
Google’s implementation was one of the first publicly available for the iPhone. They’ve apparently built a lot of infrastructure around their solution to fit within existing test systems. GHUnit attempts to integrate the unit test in the Simulator itself and the properly named OCMock does mock objects.

Recent Comments