Unit Testing an iPhone App – Not important to Apple?

December 7, 2010 by · Leave a Comment
Filed under: English, iOS 

After the base functionality of my iPhone app was in place, I wanted to have a closer look into unit testing. I try to use unit testing where it makes sense when developing for my customers, so I wanted to do that for my own app as well. I was encouraged that there was some documentation in the Apple developer’s guide, and I was really looking forward to putting the framework to use.

Restructuring my App for testability

Before being able to properly test the tax calculation functionality, I had to a bit of restructuring to do in order to properly isolate the functionality I wanted to test and to separate it from the GUI. I pulled the tax calculation into its own class and made the GUI use this TaxCalculator. This separation of concerns is one of the benefits of using a Test Driven Approach – it forces you to think about testability and separation of concerns if you want to have an easily testable class. The changed were totally unnoticeable to the user, but added some value because the code is now much easier to understand and to maintain. It took me less than an hour of development  time, and that was time well spent.

Initial Problems with SDK 4.1

The next step was reading up on Unit Testing with the iPhone SDK. There is a chapter in the iOS Development Guide that describes how to add tests to your project. From the start, I was getting strange errors even though the tests seemed to pass. As I was developing these tests while riding the train, I played a bit around in order to avoid the problems, but didn’t have any success. I added a few tests for the TaxCalculator, but ran into some more strange behaviour.

Some Progress with SDK 4.2

When I was back home, I googled for my problems and quickly found that it was a problem with SDK 4.1 (thanks to this Stackoverflow question). There seemed to be a workaround in 4.1, but as the problem was fixed in SDK 4.2, I just decided to upgrade my SDK which I wanted to do anyways.

After that, I had the next problem – XCode was telling me that my “base SDK was missing”. Googling for that problem I quickly found an easy fix for this issue as well (the one I used was on John Alexander Rowley’s blog, but there is a number of helpful hints across then net. After that, my tests were finally running without any errors and I was finally able to focus on writing test cases.

However, I soon ran into a lot of problems in properly checking what the tests were doing and if my app was working fine. I’m usually trying to reserve judgment, but in this case I can’t put it any other way:

What was Apple thinking?

Using the Apple supplied Unit Test library, the tests are only run during the build phase. Running tests during the build phase is not a bad idea, it can prevent building an app if some tests are failing. But running it only during the build phase has some serious drawbacks: Messages sent to the log do not show up in the debugger console (at least they show up in the system console), but more important: You can’t debug the tests!! (I should note that there are some descriptions on how to set up a separate target that would allow you to debug the tests, but the procedure is very complicated – like setting the environment variable CFFIXED_USER_HOME to "${HOME}/Library/Application Support/iPhone Simulator/User". I gave up on it after unsuccessfully trying for an hour or so.)

I have no idea how anyone can think that what is currently delivered is good enough to use. No one who has never used Unit Tests and pretty much wants (or has) to use it will endure the procedure to make it work. It just seems to be some item on a list that Apple wanted to tick (“Unit Testing? We have that.”) but wasn’t really interested in. Very “un-Apple” …

Switching to GHUnit

Luckily, there seems to be a good open source alternative to the Apple Unit Testing framework, name GHUnit (named after it’s developer, Gabriel Handford) which can be found at http://gabriel.github.com/gh-unit/index.html. It was very simple to download and add to my project. Within 15 minutes I had my project use GHUnit and I was able to run the previously developed tests within the simulator:

image

It also enabled me to log to the console and debug my test cases in the XCode debugger just like any normal app – without having to jump through any hoops. You may argue for a nicer interface (color anyone?), but that is certainly a minor issue. After the disappointing Apple framework, GHUnit delivered on what I was looking for. I’m hoping that the framework will hold up under all the testing I want to throw at it in the next weeks!