First, turn off ZeroLink for the application target you want to test. Just as with a framework, your unit tests will be built as a test bundle containing only the tests, completely separate from the code being tested. The test bundle will access the code in your application by linking against it, and you can't link against something built with ZeroLink. Note: You only need to do this for Xcode 2.1 through Xcode 2.5. Xcode 3.0 removed support for ZeroLink, since the linker is now sufficiently fast as to obviate it.
Next, add a new Cocoa Unit Test Bundle target to your application project. This is the target that will actually contain your tests. When you add the test bundle target, Xcode shows its Info window. In the General tab of this window, press the + button and choose your application target from the sheet that appears. This will make your test bundle target depend on your application target, so you can just build your test bundle all the time and have your application automatically rebuild first.
Now you actually need to make your test bundle link against your application. You do this using the Bundle Loader property under Linker Options in your test bundle target's configurations. You need to set the value of this option to the path of your application executable and not just its wrapper:
$(BUILT_PRODUCTS_DIR)/MyApplication.app/Contents/MacOS/MyApplication. The $(BUILT_PRODUCTS_DIR) variable is expanded at build time to be the path to the build products for the currently-selected configuration, which lets you avoid using an absolute path.The final step is to tell the unit testing infrastructure how to run your tests. For a framework, the dynamic loader does the heavy lifting; when the test rig loads your test bundle, the loader will automatically load the frameworks it depends on including the one you're testing. However, for an application to be tested the application must be launched and the test bundle injected into it. You can specify that this should happen using the Test Host property under Unit Testing in your test bundle target's configurations. Just as with the Bundle Loader property, you need to set the value to the full path of your application executable. Since you've already done that once, you can just re-use the value of the Bundle Loader setting by specifying
$(BUNDLE_LOADER) — this is the underlying variable that the property is associated with.Now just like with frameworks you can add test cases to your test bundle just by adding new files based on the Cocoa Objective-C test case class template. Your application code can remain in your application target and your unit testing code can remain in your test bundle target. Whenever you build your test bundle target, once everything is built your application will launch, its tests will be run, and it will quit — and the test results will be reported via the Build Results window just like compiler and linker errors.
2005-07-25 12:09 am (UTC)
Thanks!
Debugging
(Anonymous)
2005-08-28 03:55 pm (UTC)
-
Dave Hein
Re: Debugging
2005-08-28 06:48 pm (UTC)
Injection Rocks
(Anonymous)
2005-09-20 06:22 am (UTC)
James Duncan Davidson
tnx
(Anonymous)
2007-02-12 10:19 pm (UTC)
;))
Xcode 3.0
(Anonymous)
2007-11-17 03:29 am (UTC)
Re: Xcode 3.0
2008-03-11 09:00 pm (UTC)
Re: Xcode 3.0
2008-07-16 05:49 am (UTC)
Using Instruments with unit tests
(Anonymous)
2008-07-26 05:44 pm (UTC)
Thanks
I haven't been able to make this work
(Anonymous)
2008-09-03 02:12 am (UTC)
I'm learning Cocoa after years of working with other systems. I'm pretty familiar with the concepts, but I'm new enough to Cocoa that the syntax details are still tripping me up.
I'm writing a tutorial document on how to use XCode 3, SenTestingKit, OCMock, and git. For solving a couple of problems I had, your instructions were the best I found, but I still was not able to make it work.
I've put my tutorial and my code at http://xorandor.com/FirstCocoaApp
If you have some time, I'd appreciate some help on:
1) Running the unit tests as part of the build process in Xcode 3.1, and
2) Debugging the unit tests.
Once I get past those problem, I think I'll be able to work through my issues with OCMock and finish the tutorial.
Thanks,
Pat
Re: I haven't been able to make this work
2008-09-03 02:49 pm (UTC)
xcode-usersmailing list. I'm not the only person who can help with any issues people run into trying to use Xcode unit testing; there are lots of people using it successfully, and many are on the mailing list.Thanks.
Where to set the Bundle Loader property?
2008-11-22 11:25 pm (UTC)
Re: Where to set the Bundle Loader property?
2008-11-24 05:32 am (UTC)
Re: Where to set the Bundle Loader property?
2008-11-24 05:57 am (UTC)
The problem for me was that I had not set the Target info window to Show "All Settings"
Unexported symbols...
(Anonymous)
2009-01-17 05:54 pm (UTC)
Any suggestions for a better way to set this up? I wonder if there's some way to transform the application binary after it's built, to make its symbols exported for the Unit Test bundle's benefit.
Re: Unexported symbols...
(Anonymous)
2009-01-17 05:55 pm (UTC)
Automated procedure
(Anonymous)
2009-01-27 12:19 am (UTC)
(*
To debug the unit tests, in the "General" tab of the executable info window, the "Working Directory" must be set to "Build Products directory"
Modify the testFrameworkPath for your system
*)
set testFrameworkPath to "/Developer/Library/Frameworks/SenTestin
tell application "Xcode"
tell project of active project document
set projectName to name
set executablePath to "$(BUILT_PRODUCTS_DIR)/" & projectName & ".app/Contents/MacOS/" & projectName
tell executable name
make new launch argument with properties {name:"-SenTest All", active:true}
make new environment variable with properties {name:"DYLD_FALLBACK_FRAMEWORK_PATH", value:"$(DEVELOPER_LIBRARY_DIR)/Framewor
make new environment variable with properties {name:"XCInjectBundleInto", value:executablePath, active:true}
make new environment variable with properties {name:"XCInjectBundle", value:"Unit Tests.octest", active:true}
make new environment variable with properties {name:"DYLD_INSERT_LIBRARIES", value:"$(DEVELOPER_LIBRARY_DIR)/PrivateF
end tell
set unitTestTemplate to target template "Cocoa/Unit Test Bundle"
make new target at end of targets with data unitTestTemplate with properties {name:"Unit Tests"}
tell root group
make new group with properties {name:"Test Cases"} at beginning of groups
end tell
tell group "Linked Frameworks"
set testFrameworkFile to make new file reference with properties {full path:testFrameworkPath, name:"SenTestingKit.framework"}
end tell
add testFrameworkFile to (get link binary with libraries phase of target "Unit Tests")
set value of build setting "BUNDLE_LOADER" of build configuration "Debug" of target "Unit Tests" to executablePath
set value of build setting "TEST_HOST" of build configuration "Debug" of target "Unit Tests" to "$(BUNDLE_LOADER)"
set active target to target "Unit Tests"
end tell
end tell
activate application "Xcode"
tell application "System Events"
tell application process "Xcode"
tell outline 1 of scroll area 1 of splitter group 1 of group 1 of window projectName
tell (first row whose value of text field 1 of group 1 = "Targets")
set targetGroupDisclosureTriangle to UI element 1 of group 1
if value of targetGroupDisclosureTriangle = 0 then
perform action "AXPress" of targetGroupDisclosureTriangle
end if
end tell
select (first row whose value of text field 1 of group 1 = "Unit Tests")
end tell
perform action "AXPress" of menu item "Get Info" of menu 1 of menu bar item "File" of menu bar 1
tell window "Target “Unit Tests” Info"
click radio button "General" of tab group 1
perform action "AXPress" of button 1 of splitter group 1 of tab group 1
tell sheet 1
select (first row of outline 1 of scroll area 1 whose value of text field 1 = projectName)
click button "Add Target"
end tell
click button 1
end tell
end tell
end tell
Re: Automated procedure
2009-10-26 11:14 pm (UTC)
switch from: "tell application process" to: "tell process"
switch from: "window projectName" to: "window 1"
The former may not be necessary... I was trying to figure out the problem with running via the script menu and it may be muddled in. The latter is necessary as xcode 3.2 has a much more complex window name (or is a result of using the all-in-one project layout?).
Testing C functions ...
(Anonymous)
2009-02-13 05:57 pm (UTC)
My references to cocoa symbols resolve ok, but when I try and reference C functions defined in my application code, I get "symbol not found" errors during linking, even though nm seems to indicate that they are present in the symbol table.
exited abnormally with code 139
(Anonymous)
2009-04-01 09:36 am (UTC)
Thank you very much for the guides on unit testing cocoa apps! I've had some "weird" problems with the unittests though. in some cases the rig have filed with an error message similar to the above when I do unit test for an iPhone application. I just want to share that if I set the active SDK to Simulator - iPhone OS 2.2 all is well. I honestly have no idea why this is, and I don't have the skills to find out :)
Test Host "exited abnormally with code 127"
(Anonymous)
2009-04-08 03:23 pm (UTC)
Do these instructions apply to Xcode 3.1.2?
I have a project, the executable runs fine (It's just the default one that gets created, opens a minimally functional window.)
I've added some classes and test cases and get the formentioned error.
I did NOT set the "Target Membership" property as described in the framework version of this tutorial. I did set the Active target to the Test bundle... it had no effect.
Any ideas which way to go on this one? I did really like to develop using unit tests... in fact... i see no other way.
Thanks for these instructions and for your response in advance.
Bobby
PS. This question has been asked on the xcode-users group. No response, yet.
http://lists.apple.com/archives/xcode-us
(Anonymous)
2009-04-22 07:36 pm (UTC)
2009-09-23 10:36 am (UTC)
Hammersmith Electricians
not working on xcode 3.2
(Anonymous)
2009-11-25 05:18 pm (UTC)
???