Adding Unit Tests to an existing iOS project with Xcode 4
When you build a new iPhone or iPad app from scratch, you can generate a new project with tests using Xcode’s project templates, and the test dependency is set up correctly.
However, if you add a unit test target to an existing iOS project, there are some manual steps required to set up the target correctly. Following these steps will get you up and running quickly:
- Project MyExistingApp -> + Add Target -> iOS -> Other -> Cocoa Unit Testing Bundle
- Name the new target something like “Unit Tests” or “MyAppTests”
- Select your new “Unit Tests” target and click the Build Phases tab, expand Target Dependencies and add MyExistingApp as as a Target Dependency
- Click the Build Settings tab and set the Bundle Loader setting to
- Set the Test Host build setting to
- Go back to your app target (not the test target), set the Symbols Hidden by Default build setting to
That should take care of it, and you can now start adding tests for your app. With this configuration, you continue to add application classes only to your app target, and add test classes only to your test target. Since the tests run in the app running in the simulator, the code under test can safely instantiate views and fonts, which would otherwise cause OCunit to crash when running without the Test Host setting.
Undefined symbols for architecture i386
If you add a unit test target without following these steps, you will likely run into linker errors when you try to run tests, like the following:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_SomeClassUnderTest", referenced from: objc-class-ref in SomeTest.o
This is because your tests reference classes in your app which aren’t present in the test binary. The target dependency just causes the app to build before building the tests. Setting the Bundle Loader, Test Host, and Symbols Hidden By Default settings as described above allows the tests to link against your app, and should resolve these errors.
If you continue to see linking errors check this stack overflow post for other possible solutions (thanks Johan).