Running iOS Unit Tests Automatically Using OCUnit and Xctool

xctool is a new command line tool from Facebook which it claims makes running XCode tests much simpler. I agree. Up until now, Apple have still not given developers a simple way to automate running tests at the command line which makes testing a pain and makes continuous integration even more of a pain. It’s not impossible, but it’s not as simple as it should be.

xctool is a replacement for xcodebuild with a few extra handy features. I’m going to show you how to add this to your iOS/OSX project to greatly increase productivity and make testing more fun!

You’ll need the following before we get started:

  • Ruby 1.9.3
  • Bundler

Yeah, you heard me. Ruby. We can use the guard gem to watch to changes to our project and then fire off a build in the command line. It’s as simple as that. Firstly, we need to create a Gemfile in the root of our project.

$ cd /root/of/xcode/project
$ touch Gemfile

Open up the Gemfile and add the following:

source :rubygems
gem 'guard'
gem 'guard-shell'
gem 'fsevent', '~> 0.9'

At the command line, run:

$ bundle install

This grabs our needed gems and their dependencies. Now we’re ready for business.

With guard installed, run guard init shell at the command line. This will create a sample Guardfile to get us started. The Guardfile lists what files to watch for changes and what actions to take when changes are detected.

Open up the Guardfile and add the following lines, I’ll run through what they do in a minute:

guard 'shell' do
  watch(/(.*).(m|h|mm|hh)/) do
    puts "Change detected. Running tests..."
    `../xctool/ -project ProjectName.xcodeproj -scheme SchemeName test -reporter plain`

Line 1: guard 'shell' do tells guard to use the shell plugin we included in our Gemfile.

Line 2: This line watches our source files for changes. XCode includes lots of files, many of which change a lot and we don’t want to run our tests everytime those files change. (You might want to, I’m assuming you don’t.) This is just a regular expression which looks at any file that ends with .h, .m, .hh, or .mm (for you Objective-C++ users out there.)

Lines 3 and 4 alert the user that a file has changed, and line 4 runs xctool. You’ll need to change where your xctool is. I keep mine in the root folder of all my personal projects, I tried building a binary and adding it to /usr/bin but I was unable to get it working. You have to pass xctool the project file along with the scheme you want to build. That’s all there is to it!

Go to the root of your project and run:

$ guard

and you’re all set. Try opening your XCode project and making a change to a file. Then just watch your command line automatically run all of the tests in your project. No more clicking in XCode, clever huh?