Linking error for unit testing with XCode 4?
Asked Answered
S

1

23

I want to write some logic unit tests for classes in my XCode application. In Xcode 4, I clicked on the project name in the Project Navigator, and from the bottom clicked Add Target. I chose "Cocoa Touch Unit Testing Bundle" under Other, give the new target a "product name" of "tests", and finish.

Because the class I want to test is compiled as part of my existing application target, for my new "tests" target I immediately go to the Build Phases tab and add my existing application target as the only target dependency.

I then go to the created tests.m file, import the class I want to test (below it's ReleasePlanManager, and call one of its methods. But the linker fails with an error like:

Undefined symbols for architecture i386:
  "_OBJC_CLASS_$_ReleasePlanManager", referenced from:
      objc-class-ref in tests.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status

So the class cannot be found, even though (from my understanding) adding the application target (which it is a part of) should be sufficient?

Any help would be greatly appreciated. Thanks!

Skintight answered 23/6, 2011 at 21:57 Comment(1)
link:#6398263Tome
S
33

Your test bundle needs extra settings:

  • Set Bundle Loader to $(BUILT_PRODUCTS_DIR)/AppName.app/AppName (replacing AppName in both places with your app's name)
  • Set Test Host to $(BUNDLE_LOADER)

(If you create a project from scratch and enable unit tests, these are set up for you. But if you add a unit test bundle to an existing project, they're not.)

Susceptive answered 3/9, 2011 at 3:59 Comment(10)
It's also worth noting that your host application target must not be configured for "Symbols Hidden by Default" (in the Code Generation section of Build Settings) for the Configuration you execute your tests against. This just tripped me up earlier today on an older application.Fertile
I followed your and Blake Watters’ suggestions, now it gives me: -bundle_loader can only be used with -bundle, any ideas?Harquebusier
(may be I am facing this because I am using GHUnit and not SenTestingKit?) - for now I am including the required sources to both main target and test target.Harquebusier
(sorry for spamming) looking here #2611170, I think adding sources to both targets is the only solution, which is something I really don’t want to doHarquebusier
@ishaq, that other answer predates Xcode 4's support for injecting tests into an app. I don't use GHUnit but can't believe it would miss this feature. It sounds like your test target may be the wrong type. I'd try to re-create it from scratch, making sure to select Unit Testing Bundle. Then see if you can get one test working that depends on a class in your app.Susceptive
@JonReid too bad, I can’t use Unit Test Bundle target type, GHUnit requires target type to be some sort of application (since it has its own GUI, which is one of the features I want). adding sources to both main target and test target :/Harquebusier
@BlakeWatters You rock!! Indeed setting "Symbols Hidden by Default" to NO did the trick! (Docs say it is YES by default)Pestana
Another thing to note in Xcode 4 is that there are 2 columns to set build settings. Make sure to set it on the target, not the projectPoussin
@ishaq did you ever figure out how to get around this? regarding the GHUnit?Cissie
@Cissie no :( I ended up including sources to both targets.Harquebusier

© 2022 - 2024 — McMap. All rights reserved.