Previous Entry Share Next Entry
Xcode: Unit Testing Cocoa frameworks
It's straightforward to write unit tests for Objective-C Cocoa frameworks with Xcode 2.1 and later.

First, turn off ZeroLink when building your framework. ZeroLink is a great technology, but you can't link against something that's built with ZeroLink, and that's exactly what your unit tests are going to do. Note: You only need to do this for Xcode 2.1 through Xcode 2.5. Xcode 3.0 removed support for ZeroLink, since the linker is now sufficiently fast as to obviate it.

Next, add a new Cocoa Unit Test Bundle target to your framework project. This is the target that will actually contain your tests.

When you add the new test bundle target Xcode should bring up its Info window. Switch to its General tab and press the + button in the lower-left to add a new dependency. In the resulting sheet, choose your framework target. This tells the build system that your framework target needs to be built before your test bundle target.

Now that you've declared the dependency between the targets, you need to make sure your test bundle actually links against your framework. Make your test bundle target the active target by choosing it from the Project > Set Active Target submenu. Then highlight the Products group in the Groups & Files view at the left of the Xcode project window. In the detail view to the right, you'll see all of the products that are built by the various targets in your project; one of the rows will be for your framework. Click the checkbox at the very right of its row, in the Target Membership column, to make your test bundle link against your framework.

Now you can add test cases to your test bundle by just adding new files based on the Cocoa Objective-C test case class template. You don't need to add any of your framework code to your test bundle, and you don't need to add any testing code to your framework. And you're not restricted to using only header files with public visibility in tests, either; you should be able to use anything from your framework target, so long as it's exported at link time.

  • 1
First, turn off ZeroLink when building your framework. ZeroLink is a great technology, but you can't link against something that's built with ZeroLink, and that's exactly what your unit tests are going to do.
No need to turn off ZeroLink - it's not used for frameworks or libraries even when it's turned on. Only for applications and command-line tools.

Ah, useful. On the other hand, I'd still turn it off so the properties in my target's configurations match what actually built.

Turning Off ZwerLink

Thank you for that tip. Even though my project is an application, turning off ZeroLink allowed the unit testing target to reference the application assembly. Previously, I had resorted to adding my source files to my unit testing target, which was obviously suboptimal.

David H. Silber
dhs at the domain

Unit testing c++ in xcode 3.2.2

I'm trying to write unit tests for a c++ project.

I'm unable to add "New Target" for Carbon Unit test as such a target does not exist.
I'm using Snow Leopard and XCode 3.2.2

Kindly advice.


runtime mismatch with test rig

I first followed the Apple documentation (mainly Xcode Unit Testing Guide and Framework Programming Guide) and skipped the stuff about Bundle Loader and Test Host. When the unit test target failed to link with the framework, I right-clicked on the Link Binary With Libraries build phase and selected Add>Existing Frameworks... and linked the test target to the framework. At this point everything worked - when I built the test target, the unit tests were run successfully. I tried to do the same thing again with another project, and have not been able to get it to work again. The error is : "UnitTests.octest could not be loaded because its Objective-C runtime information does not match the runtime information required by the test rig. This is likely because the test rig is being run with Objective-C garbage collection disabled, but the test bundle requires Objective-C garbage collection. To enable Objective-C garbage collection for the test rig, run it in an environment without the OBJC_DISABLE_GC environment variable." I found several web pages referencing the tutorials here and I tried what's explained here with a new project. The only real difference is using the target check box to get the link happening, but it seems very much what I did originally. But again I've gotten the error listed above about information mis-match. Both targets have Objective-C Garbage Collection set to Unsupported and the code is reference counted. Any ideas as to what might be going on? Suggestions most welcome. Best regards, Bob

  • 1

Log in