iOS: Setting Up Basic Unit Testing

After a short introduction in my first iOS testing article I will describe how I set up basic unit testing on iOS.

Complication No. 1, “the Apple way”: XCode comes with a unit test framwork, OCUnit, but unfortunately its integration is a little bit strange. You create an octest bundle that’s “somehow” (I didn’t try to understand how this is working in detail) loaded into your normal project target and then will run your unit tests.

Usually I would simply create a second binary that contains the test sources and the production sources and links to the same libraries plus the libraries needed for testing.

The only advantage I see in using the bundle approach is that I do not have to create a test target with nearly the same setup for the unit tests (copying all settings, adding all classes you want to test and so on…).

One annoying drawback is setting it up for debugging. Sometimes it is useful to step trough a test to understand where it is going wrong but you will need additional setup to debug your unit tests with breakpoints. That’s inconvenient but possible without to much work for normal MacOSX development (i.e not iOS). For iOS this is getting more complicated. As the article says: “What a mess”.

Another drawback is that you can’t run the tests in the simulator or on the device itself because your test bundle is not an ordinary iOS app.

Solution to Complication No. 1: While looking for iPhone/iOS test resources I found Google Toolbox for Mac (GTM). First I was wondering why I would need it but after being a little bit ;-) frustrated by the setup of the standard Apple way above, I gave it a try.

Basically you create a normal standalone iOS app as part of your project. You just have to add a couple of GTM source files to your test target app (a copy of the production app), setup a “run script” build phase (to run the test after they are built) and you are done. This is described in the GTM iPhoneUnitTesting instructions.

Note: I had to remove the MainWindow.xib from the plist file created for my test target. With the xib set I got some complains about the app being unable to load it.

CI Tip: I copied the required files of GTM to my subversion project so I do not have to link to external files when I’m going to setup the Jenkins/Hudson build. 2011/2: See also iOS: Setting Up Advanced Unit Testing Take Two.

The only difference for creating new tests is that you have to use GTMTestCase as base class instead of SenTestCase. But that is not a big issue and GTMTestCase itself is based on SenTestCase. Which is nice because it will automatically play well with OCMock and OCHamcrest (which will be covered in the next article).

A lot simpler than the default way. Nice is that you will not need any extra setup to step into your test code. Just set breakpoints and run the test target. And because it is an ordinary app it will run in the simulator and on the device.

GTM has more stuff to explore (e.g. support for UI testing, additional asserts) but I have not yet played with it.

Summary: with GTM I can easily debug my test cases and run the test in the simulator and on the device. Not bad!

Advice: go with Google Toolbox for Mac for unit testing on iOS.

In iOS: Setting Up Advanced Unit Testing I will pimp the unit testing environment with OCMock and OCHamcrest which has a few new complications.

This is the 2nd article of iOS: Setting Up a Test Environment is a Mess.

iOS: Setting Up a Test Environment is a Mess

Really. I have tried. I have done it successfully but it was a bit of work.

There are a number of complications to set up a decent testing environment for iOS. I will describe which tools I choose and what I had to do to get everything running. I will not describe everything in detail but hopefully it will still give you a starting point.

All in all, I think that this should be (a lot) easier, even in this part of the C universe.

So what do I consider a decent testing environment?

I think at first we need support for unit tests and acceptance tests (in the agile meaning). Unit tests to get the low level stuff right (we can also use it for some integration testing) and acceptance tests to do some end-to-end testing.

Running all the tests manually is not a good idea anymore so I will run them on a continuous integration server, which will also take care of collecting code coverage.

My current collection of tools include XCode (xcodebuild, gcc, gcov) with iOS SDK, Google Toolbox for MacOCMock, OCHamcrest, Cucumber, Frank (includes UISpec) and Jenkins/Hudson (with gcovr for xml-ifying gcov).

All tools are free and all I had to do was to make them play together. A number of blogs provided helpful information. I will try to list them for reference.

There is a lot of stuff and to make it an easier read I split in into multiple articles. Here is the complete list:

February 2011: Here is new article regarding setup of OCMock & OCHamcrest:

Ok, let’s start with iOS: Setting Up Basic Unit Testing.