Home > iOS, Mobile Development, Objective-C > Xcode3 – Debugging iOS Unit Tests

Xcode3 – Debugging iOS Unit Tests

 

So you have some unit tests (yeah!) and they are failing …. now what?

 
Over the course of my career these past few years, I have become a developer that writes more test code than production code in an effort to never have to spend the wee hours of the morning debugging a horrible production issue. As a java developer turned mobile developer, there are several things that I miss about coding in Java but the number one thing is unit tests.

Don’t get me wrong – I know what you are thinking – probably something along the lines of: “Do a little research dummy! Xcode has a nice Unit Test Bundle target that we can use to run unit tests! All you have to do is write them!” Right…..

Or maybe after a little more googling around you may even point me to this excellent Apple documentation that explains the process of setting up and running my newly created unit tests but there is a huge section missing from this guide…

iOS Development Guide: Unit Testing Applications

So I have followed all these steps and everything is running fine and dandy until …I need to debug my tests. Where is the guide for this? What’s the point of having tests if I can’t debug them???

Having spent countless hours reading blog posts and attempting steps I have finally gotten it working with Xcode 3.2 AND iOS 4.2 as of today! Yes today! Not two years ago and not on some old version of Xcode and some weird version of the iOS SDK so to save you from having to experience this same misery keep on reading.
 

Have no fear! Instructions are finally here!

 
This guide assumes that you have the following knowledge, skills, and tools:

  1. Apple computer that has the Developer Tools installed and up to date.
  2. Working knowledge of Xcode 3.2, Xcode projects, Xcode build targets
  3. Working knowledge of Objective-C and iOS development

With the above, you should be able to follow these steps fairly easily so I won’t go into details on the typical tasks. If you need more information on how to use Xcode or setting up targets please see the following guide: Understanding Xcode Projects

Here we go…

    Create a new Xcode project

  1. Open Xcode 3 (instructions coming later for Xcode4)
  2. Create a new Xcode project (iOS window-based application template) — mine is called “MyNewApp”
  3. Build and Run the project for the simulator – if its “just working” – and it should – you should see a blank white screen in the simulator.

    Create a new target and run some tests

  1. Select “Targets” and add a new target (Unit Test Bundle template) — mine is called “MyNewAppTests”
  2. Expand the build phases of the new target and take note of the last step – “Run Script” – this is the step that runs your tests as part of the build.
  3. Add a new Objective-C Test class to the project, make sure you add it to the “MyNewAppTests” target.
  4. Within the new “MyNewAppTests.m” file add the following code:
    - (void) testFail {
    STFail(@"Must fail to succeed.");
    }
    
  5. Select the “MyNewAppTests” as the active target and run the build – it should fail

These steps are a shortened version of this guide: iOS Development Guide: Unit Testing Applications. If you need more detail to get your initial units tests building and running – please see the full documentation.
 

It’s failing … now its time to debug!

 
To debug your tests you need to set up an alternate method to run the tests – the basic “Run Script” in the typical test bundle target actually runs a “RunUnitTests.sh” which ultimately launches an instance of “otest” to run the tests — but its not debuggable and runs standalone.

In order to create your own executable to run “otest” and debug it – you will need to run the following command to find the right otest executable for your current iOS SDK.

Run this in the Terminal: find /Developer -name otest

When I run this I see a number of options — select the one from the latest iPhoneSimulator#.#.sdk — and take note of the path.

[hiedi:/Developer/Tools] % find /Developer -name otest
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.2.sdk/Developer/usr/bin/otest
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.0.sdk/Developer/usr/bin/otest
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.1.sdk/Developer/usr/bin/otest
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/Developer/usr/bin/otest
/Developer/Source/OCUnit/SourceCode/otest

 

    Create another new target and an executable

  1. Select “Targets” and add a new target (Unit Test Bundle template) — mine is called “MyNewAppTestsDebug”
  2. Expand the build phases of the new target — delete the last build phase — “Run Script”
  3. Right click and “Get Info” on the “MyNewAppTests.m” — add “MyNewAppTestsDebug” to the list of included targets.
  4. Select “Executables” and add a new custom executable with any name — mine is “Debuggable Otest” and fill in the path that you found above.
  5. On the arguments tab — add an argument that specifies the test bundle to use — mine is “MyNewAppTestsDebug.octest”.

On the arguments tab — also add the following environment variables:

Variable Value
DYLD_FRAMEWORK_PATH ${SDKROOT}/Developer/Library/Frameworks
DYLD_LIBRARY_PATH ${BUILD_PRODUCTS_DIR}:${DYLD_LIBRARY_PATH}
DYLD_NEW_LOCAL_SHARED_REGIONS YES
DYLD_NO_FIX_PREBINDING YES
DYLD_ROOT_PATH $SDKROOT
IPHONE_SIMULATOR_ROOT $SDKROOT

    Run the new target and executable

  1. Set the new target and the new executable as active and then Build/Run
  2. Open the console – you should see messages relating to the running of your tests and their failure.
  3. Now set a breakpoint in the “MyNewAppTests,m” file then Build/Debug
  4. In the console you should see messages about resolving your breakpoint and then it should stop in the debugger.

Note: These steps have been adapted from an original blog post by the author of Grokking Cocoa and can be found here: How to Debug iPhone Unit Tests

About these ads
  1. szeryf
    March 20, 2011 at 6:02 PM | #1

    Good stuff. Thanks for this article. Tried out several solutions with no results, yours is the one that worked.

  2. Brad Howes
    May 26, 2011 at 11:49 AM | #3

    Thanks from me too. I *finally* got debuggable unit tests under Xcode 3.2.6. I wish your post had appeared before the others since I spend days tracking down broken stuff. Ugh.

  3. Ben
    August 7, 2011 at 5:37 PM | #4

    Thanx a million! I tried many solutions I found but never got it working.
    Your explanation made debugging possible for me, great stuff.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com 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

Follow

Get every new post delivered to your Inbox.

Join 33 other followers

%d bloggers like this: