Creating unit tests in XCode

Add unit test target

  • Select Targets group and select Add|New Target…|Unit Test Bundle
  • Setup dependent test bundle
    • Double-click test unit target to display it’s info. Select General tab and add project to be tested to dependencies
    • Select Build tab and set Bundle Loader value to $(BUILT_PRODUCTS_DIR)/
      if you are testing application and to $(BUILT_PRODUCTS_DIR)/MyApp if you are testing framework. Set Test Host value to $(BUNDLE_LOADER)

Debugging unit tests

Mostly this is taken from Chris Hanson’s blog but contains one adjustment

When you add the custom executable, Xcode will bring up its info window. Switch to the Arguments tab. Here you’ll need to enter some command-line arguments to pass to the test rig and some environment variables to affect how it’s run. In the arguments tab of your application executable, first add an environment variable named DYLD_INSERT_LIBRARIES. Set its value to $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/DevToolsBundleInjection.framework/DevToolsBundleInjection . Then add a second environment variable, XCInjectBundle. Set its value to MyTestBundle.octest . (Originally, it was $(BUILT_PRODUCTS_DIR)/MyTestBundle.octest but that didn’t work for me. See this answer for details). Make sure the check marks next to both of these environment variables — and your -SenTest All argument, of course — are set.

To actually debug a failing test, build your tests and set a breakpoint on the line where the failure occurs. Now choose Debug Executable from the Debug menu. Do not choose Build and Debug from the Build menu. You need to use Debug Executable because your build will fail due to the failing test; Debug Executable doesn’t try to build first, it only cares whether an executable is present.

You should successfully stop at your breakpoint!

If your tests take a long time to run — they shouldn’t, they’re unit tests after all, but it can still happen — you may want to just run the tests for one test case, or just one individual test. This is easy too. Rather than specifying -SenTest All in your arguments to otest, you can specify -SenTest MyTestCaseClassName to run the all the tests in the specified test case. To run just a single test, use -SenTest MyTestCaseClassName/testMethodName instead.



Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s