Unit Testing Tutorial for iOS: Xcode 4 Quick Start Guide
A unit testing tutorial for iOS and xCode 4. By .
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Unit Testing Tutorial for iOS: Xcode 4 Quick Start Guide
15 mins
Unit testing is great because it makes your life easier. Easier to deliver high quality code, and easier to make changes without fear of breaking something!
But what might not be so easy is getting started if you’re new to unit testing – and that’s what this tutorial is all about!
We’ll cover how to set up Xcode to use three different unit testing frameworks:
- OCUnit, which is the unit testing framework built into Xcode
- GHUnit, which is a third party framework with some extra cool features
- OCMock, which helps you write mock objects to aid tricky testing scenarios
We won’t cover how to actually write test cases in this unit testing tutorial, but don’t worry – I’ll be covering that in my upcoming tutorial series on Test Driven Development for iOS!
This unit testing tutorial assumes you already know the basics of iOS development. If you are a complete beginner, check out some of these Beginner iOS Tutorials first.
Getting Started with OCUnit
OCUnit is the unit testing framework that’s built straight into Xcode, so let’s try that out first.
In Xcode, go to File\New\New Project, select iOS\Application\View-based Application, and click Next. Name the project SampleProject, and make sure to check the Include Unit Tests option, as shown below.
Click Next, choose a folder for your project, and click Create.
If you look at the generated project, you’ll see that Xcode has created two targets for you: SampleProject (the app target), and SampleProjectTests (the unit test target).
The unit test target is created with a dependency on the app target, so that when you run the tests, the app target will automatically be built.
Xcode also creates a single test class as an example for you, which you can find in SampleProjectTests\SampleProjectTests.m. You’ll see a single test case set up in the file that looks like this:
- (void)testExample
{
STFail(@"Unit tests are not implemented yet in SampleProjectTests");
}
Basically this is a sample test that should fail immediately when it’s run, because you haven’t written any unit tests yet!
Let’s try this out and see if it indeed fails like it should. Select the iPhone Simulator from the Scheme drop down, then choose Product\Test from the Xcode menu (shortcut key ⌘U).
Xcode will then build the app target, then build the unit test target. If both targets can be built it then runs the test cases on the simulator and highlights any failures in the Issue Navigator and in the source file itself, just like it does with build warnings and errors.
So as you can see, setting up unit testing with OCUnit in Xcode is really easy – it’s just a matter of selecting a checkbox!
We won’t get into how to use write unit tests with OCUnit in this unit testing tutorial series, since I prefer the alternative unit testing frameworks GHUnit and OCMock which we’ll cover next.
However, if you decide OCUnit is right for you, check out Apple’s Unit Testing Overview for more information on how you can write your own tests.
GHUnit vs OCUnit
GHUnit is a popular unit testing framework developed by Gabriel Handford as an alternative to OCUnit. With the release of Xcode 4, using OCUnit is better than it used to be, but I still prefer GHUnit because:
- GHUnit allows you to run all tests, a single test, or just the failed tests, while OCUnit can only run all of them.
- GHUnit comes with a neat test runner app, that quickly shows you a high level view of passing and failing tests, while OCUnit does not have this.
- GHUnit is an open source project, so you can modify the framework to better meet your needs.
OCUnit does still have the advantage of being tightly integrated with Xcode, which makes the initial project setup easier, but to me the advantages of GHUnit outweigh this.
If you’re interested in reading more about the differences between GHUnit and OCUnit, check out this nice comparison by Mark Makdad.
Introducing OCMock
Before we cover how to integrate GHUnit into your Xcode project, let’s take a minute to discuss OCMock.
If you have ever written automated unit tests before, you probably have encountered the problem of trying to test more than one class at a time.
This is a recipe for brittle tests and spaghetti code. After a while, you get to the point that you’re ready to throw the tangled mess into the trash!
Using some form of dummy objects (also known as mock objects) to reduce dependencies is a good method to solve this.
Mock objects allow you to test interactions with the outside world while keeping external dependencies as low as possible. If your code has external dependencies or responsibilities (and most do), you’ll want to use these!
OCMock is a framework for OS X and iOS developed by Mulle Kybernetik that follows the pattern of mock frameworks developed for other platforms.
So you’ll learn how to set up Xcode to use this along with GHUnit!
Installing GHUnit and OCMock: Overview
These instructions will create a project structure with all files stored in the actual project directory, including the GHUnit and OCMock frameworks. These instructions also assume everything we create or download will be in the directory ~/myproj, but feel free to put them wherever you like.
After each step in the process, you should do a clean, build, and run for each target to validate the configuration and dependencies.
We will use the name MyProj for our project and derive several targets and file names from it. You can choose whatever name you wish, but it is best to be consistent in your naming of targets and components.
There are many more options for GHUnit and OCMock, but they are outside the scope of these instructions. For more information, see the Other Links at the end of this post.