I just did a re-check on the state of the art for this. Summary: in early 2010, Apple’s support for unit-testing real-world iPhone projects is disappointing. But that’s OK, because after much digging and experimenting, I’ve found an open-source alternative that’s much simpler, (so far) fully works – and provides a lot more functionality than Apple’s imported one.
Apple’s Unit Testing: didn’t work for me
I include this FYI, for people who want to try this route. I know it works for some people – but most people I know have given up on it. It worked for me, then it suddenly stopped working, and never worked again (linker errors). YMMV.
First of all, bear in mind that this is OS 3.0 and above only. That’s probably not an issue for most developers – I rarely meet anyone these days who’s still developing for it. Apple didn’t want us developers to continue supporting it, and fortunately “most” users upgraded anyway.
More importantly, from the official Apple docs on Unit Testing:
“Xcode offers two types of unit tests: logic tests and application tests.
Logic tests. These tests check the correct functionality of your code in a clean-room environment; that is, your code is not run inside an application.”
[lots more follows]
The rest is fairly unimportant. The key message is this: these “logic” tests are useless. They cannot be used with any real functionality for an app. They’re pretty much limited to writing iPhone apps that do “what does 1 + 1 equal?” – and which HAVE NO GRAPHICS OR USER INTERACTION.
Not even networking is going to work here – so you can forget testing any of the bits of your app that are likely to actually need testing…
The other kind of testing – “application” tests – Apple doesn’t document for static library projects. A long time ago it used to be verboten (Apple had hard-coded Xcode to actively prevent you from doing this), but it seems that’s changed, and it’s now technically possible. But … with apparently no official docs from Apple, I couldn’t get it to work.
If you want unit tests in Objective-C on iPhone, and want them to work properly, and want them to work on static libs … you have to write the testing framework yourself. This is not so hard – mu_test is one framework in C that is less than 5 lines of code (although it’s very weak on features! ). I guess it’s time for me to brush up on C macro writing (ugh). Or maybe not. I’m not going back to that ugly place .
So, what next? Have a look at who else has already done that…
3rd party Unit Testing for iPhone apps: A new hope
ObjcUnit – link
I thought this should be the best option, it’s named after the most mainstream of Unit-Testing frameworks. Try it, and you quickly spot that sadly it’s not been updated in 8 years. That’s not so bad – good unit testing frameworks need little in the way of updates. However, it also appears to pre-date the existence of Xcode, which is more worrying. Unfortunately, the provider (Oops) is well-named: the wiki which contains “all” the instructions, and is linked from that page, has apparently been taken off-line. Oops!
iPhoneUnitTesting – link
Name sounds pretty good . Let’s see … Hmm. It’s a Google Toolkit for Mac project (Google iPhone libs are good but tend to be slow to compile and lack basic documentation).
On further investigation … this is an earlier version of the same port that Apple used, which resulted in my lack of success above. Given that I can’t get Apple’s more official version to work, it’s useless – although … it would at least bypass Apple’s hard-coded attempts to prevent you from using the framework version. But I’d have to manually do it all. I’m not eager to go there, if I can find something smoother.
WiteBox – link
Silly name, but … some excitement here … it actually mentions iPad in the brief docs! This suggests it’s very up to date, and might work well.
So, I follow the instructions, it fails. Start again, using my knowledge of Xcode bugs. Still fails, but for a different reason. Start AGAIN, using my experience of XCode Targets madness, and dependent builds. SUCCESS!
Even better, this one provides you with a basic test GUI. This is a standard feature of Unit Testing on all other platforms (not sure why Apple didn’t bother; it really makes OS X / Xcode look bad). This one is more than “basic”, it lets you drill-down into the fail/success reports using the classic iPhone GUI. Here’s a couple of screenshots:
At this point, I stopped. I finally had a working unit-testing system on iPhone (I’ve spent the last 2 years doing hacks to achieve the same end-purpose, but they’re creaking under the strain).
Even better, I’ve now got a nice funky GUI to run my tests on. Excellent!
Addendum: Changes I made to get WiteBox working with static libs
Quick list of changes I needed to make to the “install” process (it’s not bugs in WiteBox, it’s just an overly brief install guide )
- Make sure when you drag/drop import the folders WiteBox and WiteBox-iPhone … that you select “Recursively create groups for any added folders” (the docs don’t seem to mention this, but if you don’t, Xcode ignores the source files)
- Add all the frameworks for your static lib to the WiteBox target you created; this is normal practice for when you try to “use” a static lib, you have to add its “expected” frameworks by hand, but it’s easy to forget here
- Drag/drop your static lib “target ” into the WiteBox app. If you’re not yet using Universal Binaries, you’ve probably got one lib for simulator, and a different one for device – drag whichever one for the way you intend to run Witebox (I only run it on the simulator, for fast local testing)