How to Create an iPhone Project in Xcode That Can Run Unit Tests

This is the second part of a blog series I am writing on How to Do iPhone Unit Testing or Lessons Learned from Unit Testing iPhone Apps.

I am targeting this at iPhone Developers.  My aim is to take you step by step through the process of setting up an iPhone Project in Xcode that lets you run unit tests.  There are other guides out there but I’d like to make this very visual and easy.

So let’s get to the question:

How do I set up an iPhone project that lets me unit test my app?

Step 1:  Create a New iPhone Project

Create a new project via File > New Project.  Choose “View-Based Application” (you can choose any, but we’ll use this type here.)  Name your project “example1” to follow along with this tutorial.

After your project is created, it should look something like this:

 

The "example1" project after creation.
The "example1" project after creation.

 

Now that you have created the project, you can add the supporting files to enable unit testing.

Step 2: Create a Folder to Organize Your Unit Testing “Framework”

One of the lessons learned from my iPhone consulting is that iPhone projects can get big and messy.  It helps if you isolate your “frameworks” into folders in Finder.  I say “frameworks” loosely because you can’t really have Mac OS X-style frameworks in your iPhone projects.  There is no dynamic loading of libraries (which frameworks are) on the iPhone.  Instead, you end up copying all the files into your project.

In this example, we will create a folder named “UnitTestingFramework” in our project to separate it from the rest of our code.  If you’re using a lot of external code in your project, you could put this under another folder called “OpenSourceFrameworks.”  I’ve done this in most of my consulting projects, but we’ll keep it simple since we’re only working with one “framework” in this tutorial.

So: In Finder, create a new Folder inside your “example1” project folder called “UnitTestingFramework.”

 

Create a folder named UnitTestingFramework in the example1 project folder.
Create a folder named UnitTestingFramework in the example1 project folder.

Drag and drop the “UnitTestingFramework” folder from Finder into the “example1” project in Xcode.  When the sheet pops up, do not select “Copy items into destination group’s folder (if needed).”  The reason is because it already is in the “example1” folder.

You should see a Group called “UnitTestingFramework” underneath the “example1” Project.

 

You should see a UnitTestingFramework group underneath the example1 project.
You should see a UnitTestingFramework group underneath the example1 project.

Step 3: Find and Install a Unit Testing Framework

In the first post, I alluded to a group of “diligent and ingenious engineers”.  I was specifically referring to the Google Mac Team.  They’ve created a great project called Google Toolbox for Mac.  It actually does a lot more than unit testing.  For example, I used their Address Book interface to make working with Address Book on the iPhone much nicer.

In this tutorial, we’ll focus on one subset of Google Toolbox for Mac, the unit testing portion.  We won’t even use the entire unit testing portion, since there are helpers for Mac OS X unit testing as well.

First, you’ll need to download the source.  The latest stable version is their 1.5.1 from June of 2008.  You can get it from here: google-toolbox-for-mac-1-5-1.zip

You could also get the latest from Subversion, but we’ll focus on the stable version for this tutorial.

Unzip the file by double-clicking on it in Finder if it wasn’t unzipped already into a folder.  Then go into the folder and find the following 7 files:

GTMDefines.h

UnitTesting/GTMIPhoneUnitTestDelegate.h

UnitTesting/GTMIPhoneUnitTestDelegate.m

UnitTesting/GTMIPhoneUnitTestMain.m

UnitTesting/GTMSenTestCase.h

UnitTesting/GTMSenTestCase.m

UnitTesting/RunIPhoneUnitTest.sh

 

The 7 files you need to select from Google Toolbox for Mac.
The 7 files you need to select from Google Toolbox for Mac.

Drag and drop those 7 selected files to the “UnitTestingFramework” group in Xcode.  When the sheet appears, make sure to check “Copy items into destination group’s folder (if needed.)”  This time, we need to copy them from the Google Toolbox for Mac download to our project and specifically to the UnitTestingFramework folder we created in Step 2.

You have all the raw ingredients now, but you will need to perform a few more steps to be able to find and run unit tests in your iPhone project.

Step 4: Create a “Tests” Target

Create a new target via Project > New Target.

Choose iPhone OS > Cocoa Touch > Application.

Call it “Tests”.

In the first post of this series, we discussed that there are only two types of Targets available for iPhone projects.  Applications are the only ones that can run and we want to execute our unit tests.  That is why we are adding this new “Tests” target.

We are almost there.  Now we just need to tell the “Tests” target to find and execute our unit tests.

Step 5: Add a Run Script Build Phase to the “Tests” Target

Select the “Tests” target.

Control-click (or right-click or whatever finger gestures you use on your fancy new MacBook Pro with no buttons) and select Add > New Build Phase > New Run Script Build Phase.

Enter “./UnitTestingFramework/RunIPhoneUnitTest.sh” in the Script text area.  Note that if you had spaces in your folder, you would need to escape it with a backslash like “\ ” here.  So another lesson is to not include spaces in your folders to keep things simple.

 

Enter "./UnitTestingFramework/RunIPhoneUnitTest.sh" in the Script text area.
Enter "./UnitTestingFramework/RunIPhoneUnitTest.sh" in the Script text area.

What is this “RunIPhoneUnitTest.sh”?

It is a shell script that the Google Mac team has created.  It sets up some environment variables to help with executing the unit tests.  The real magic will be explained later in this series.  Hint: it is in those files you selected and dragged into your project.

Step 6: Ensure All the “UnitTestingFramework” Files Are Part of the “Tests” Target

Select the “Tests” target in the Active Target portion of the Toolbar.  You can also select in via the menu item Project > Set Active Target > Tests.  Ensure tha the Active Build Configuration is Debug and the Active SDK is Simulator.

Select the UnitTestingFramework group.  Look at the list on the right side and make sure that all the *.m files are checked.  This ensures that they will be included in the Tests target.  Check any that are unchecked.

Note that you’ll want to make sure these are all unchecked in your “example1” target as well.  You don’t need these testing “framework” files in your regular application target.

 

Check all the UnitTestingFramework *.m files for the Tests target.
Check all the UnitTestingFramework *.m files for the Tests target.

 

Step 7: Run the Tests and Verify Success

At this point, the project is fully set up to run unit tests for an iPhone project.  To verify this, press the Build button on the toolbar or use the menu item Build > Build.

Open up the Build Results so you can see the progress.  You can use the menu item Build > Build Results.

To better see the progress, you will want to look at the detailed Build Transcript.  To see this, you’ll need to click on the little transcript icon in the Build Results window.

 

Click on the Build Transcript button to see the details of the unit tests progress.
Click on the Build Transcript button to see the details of the unit tests progress.

You should see: (give or take a few miliseconds)

“Executed 0 tests, with 0 failures (0 unexpected) in 0.004 (0.004) seconds”.

This is success!  Your project is set up correctly.  We have no tests yet.  We will cover that tomorrow.  But this shows that the unit testing “framework” is running correctly.  If we did have any tests, they would execute and show in the Build Details.

If you don’t see this, don’t worry – try reading part 4 of this series: Pitfalls That You May Encounter when Running iPhone Unit Tests and How to Overcome Them.  You can also visit the Google Toolbox for Mac Google Group for support via an email discussion list.

Note that the results were reported twice – this is a known bug in 1.5.1 and is fixed in a later version.

You can see the completed version of this project at http://github.com/luisdelarosa/iphone_unit_testing.  That’s sort of like when you see a chef pull out a fully cooked pie at the end of  cooking show.

If you have any questions about this tutorial, let me know in the comments.

4 Replies to “How to Create an iPhone Project in Xcode That Can Run Unit Tests”

  1. Great detail in this post for getting started with iPhone testing.

    I’ve documented a similar process (without the informative screenshots) and also included Hamcrest and OCMock in my testing toolkit. Hamcrest provides significantly better assertions than the SenTest API and OCMock is indispensable for breaking dependencies in the SDK UI classes.

    http://blog.carbonfive.com/2009/02/testing/iphone-unit-testing-toolkit

    BTW, you can use frameworks in xCode to develop and test your iPhone project, you just can’t deploy them to the device. So frameworks for testing work fine with the proper setup in xCode.

  2. I have been exploring unit testing in xcode and stumbled across this. Looks like a solid and detailed tutorial to get things up and running. I am definitely going to check it out.

  3. I think in the line:
    Create a new target via Project > New Project.

    You mean to say:
    Create a new target via Project > New Target.

    Louie: Thanks! I updated the post to reflect that.

  4. Using GTM trunk as of October 2009, you also need to add GTMObjCRuntime.h and GTMObjCRuntime.m to your project.

Comments are closed.