views:

272

answers:

2

I'm trying to setup application unit tests for my iphone app. So I made a copy of the app target, and a unit test bundle target as described in apple's documentation.

After following Apple's directions, I wasn't able to reference my classes in the unit tests, so I linked the app into the unit test bundle using the "Bundle Loader" build setting and setting the main target to export symbols. That resolved the compilation time errors, and it worked and executed my tests immediately after I changed it. But once I cleaned and built again, I started getting this error when I tried to run on the device:

Unable to read symbols for "/Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.1 (7C144)/Symbols/Developer/Library/PrivateFrameworks/DevToolsBundleInjection.framework/DevToolsBundleInjection" (file not found).

It's true that the file doesn't exist. I found the .framework file under: /Xcode3.1.4/Library/PrivateFrameworks PrivateFrameworks

and made a symbolic link. Then running the app said that it couldn't link the app's files:

010-01-25 20:19:22.330 SmokeyTheBear[5808:207] Error loading /private/var/mobile/Applications/26E1F8F4-6444-415B-84CB-BB161DBA29E9/SmokeyTheBear.app/LogicTests.octest/LogicTests:  dlopen(/private/var/mobile/Applications/26E1F8F4-6444-415B-84CB-BB161DBA29E9/SmokeyTheBear.app/LogicTests.octest/LogicTests, 262): Symbol not found: _OBJC_CLASS_$_AppDelegate
  Referenced from: /private/var/mobile/Applications/26E1F8F4-6444-415B-84CB-BB161DBA29E9/SmokeyTheBear.app/LogicTests.octest/LogicTests
  Expected in: /var/mobile/Applications/26E1F8F4-6444-415B-84CB-BB161DBA29E9/SmokeyTheBear.app/UDorse
 in /private/var/mobile/Applications/26E1F8F4-6444-415B-84CB-BB161DBA29E9/SmokeyTheBear.app/LogicTests.octest/LogicTests
DevToolsBundleInjection: Error loading bundle '/private/var/mobile/Applications/26E1F8F4-6444-415B-84CB-BB161DBA29E9/SmokeyTheBear.app/LogicTests.octest'

Then, I switched back to running the normal target for the app, and it ran all my unit tests and exited! I cleaned again and built, and then the normal target ran normally. The unit test target still didn't work.

A: 

Hello Andrew, while this doesn't answer your question directly, I wanted to say that I tried following your route using Apple's unit testing information and found it to be a non optimal TDD approach, so I opted to use what other people recommended :

Google's Toolbox iPhoneUnitTesting Kit

UISpec for GUI unit testing

Tutorial about how to get this running and a discusion about the different options available for iPhone unit testing.

I think the option provided by apple can only run in simulator mode, and have many other disadvantages... sorry for not answering your question directly but maybe you could tackle the problem with a different perspective ( like the ones I posted you here ).

Mr.Gando
+1  A: 

From the log messages given, I assume you are trying to setup a "logic test" (awkward, isn't it?). Your problem is that you try linking to your to-be-tested code when it needs to be included in the testbundle instead. Here's the relevant section of the manual (emphasis mine).

For a test case to access the subject API, you may have to add the appropriate implementation files to the unit-test bundle and import the corresponding header files into your unit-test class. For an example of a project that uses unit tests, see the iPhoneUnitTests sample-code project.

I have found unit testing setup with OCUnit to be a suboptimal experience too. Unit testing simply isn't a first class practice in the Obj-C world, at least from what is provided by Apple. OCTest is a customized version of the SenTestingKit. Basically it creates a library with the extension .octest that the OCTest runner (otest) executes. Dynamic linking isn't supported (better phrased: allowed) on the iPhone, so that's why you are left of running your tests on your mac only.

That's the simple case of "logic tests", "application tests" are a little more complex. The way OCUnit works causes all sorts of pain, especially with debugging. That's why me and many others opted out of OCTest and choose GTM or GHUnit. They work via static linking and including the test-runner in the test-target itself. (Somewhat similar to "application tests".)

Johannes Rudolph
oh, and btw, you should really check out the sample project if there's anything left unclear.
Johannes Rudolph