It's simple. All you have to do is set up an appropriate Executable in Xcode to run the test rig that runs your bundle, and then debug that. To get started, choose the Project > New Custom Executable menu item. For its name, specify
otest— this is the name of the test rig used by OCUnit. Specify
/Developer/Tools/otestas the path to your tool.
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.
First, add the argument
-SenTest Selfto your executable. This tells
otestto run all of the tests in your bundle. (It's actually a pair of arguments, but you can add it as one as a convenience.) Then for your second argument specify
$(BUILT_PRODUCTS_DIR)/MyTestBundle.octestwhere MyTestBundle is the name of your test bundle. This tells
otestthe path of the test bundle to load;
$(BUILT_PRODUCTS_DIR)will be expanded to the appropriate build products directory for your project at run time. (If you get the order wrong, just drag the arguments around in the table.)
Troubleshooting note: If this doesn't work — that is, if
otestcomplains it can't find your test bundle — change the executable's working directory (in the General tab) to Built Products Directory and remove
$(BUILT_PRODUCTS_DIR)above. Generally this is caused by
$(BUILT_PRODUCTS_DIR)not being expanded to a full path, but rather to a partial path relative to your project directory.
Next add a pair of environment variables named
DYLD_LIBRARY_PATHto your executable. These will tell the loader to check your build products directory first for frameworks and libraries whenever the executable is run from within Xcode. Specify
$(BUILT_PRODUCTS_DIR)for the value of each variable.
Finally, from the Project > Set Active Executable menu choose your new otest executable. This way any time you run or debug within Xcode, it will run
otestwith the arguments and environment you've specified.
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 Selfin your arguments to
otest, you can specify
-SenTest MyTestCaseClassNameto run the all the tests in the specified test case. To run just a single test, use
Update July 7, 2007: Added the troubleshooting note about removing
$(BUILT_PRODUCTS_DIR)if you get errors about not being able to load the bundle.