Xcode 4 unit testing linker error
Asked Answered
P

9

18

NOTE: "Use GHUnit" is not an acceptable answer to this question. I know most think GHUnit is better than the Xcode4 OCUnit, but that's not what I'm asking about. I'll evaluate that separately.

I have an Xcode project that I created in Xcode4 from scratch, with the "Include unit tests" checkbox checked during creation. I have also included some libraries I developed in a previous project. They were added to the project via the "Add Files to x..." dialog and only added to the application target (not the testing target). They work fine when running the application, so I think they're set up correctly. I also have a number of various classes written for this project.

My testing files are set up in the standard way, named [AppName]Tests.h and .m.
Code for header:
#import < SenTestingKit/SenTestingKit.h >

@interface [AppName]Tests : SenTestCase {
@private
}
@end

Code for implementation:
#import "[AppName]Tests.h"

@implementation [AppName]Tests

- (void)setUp
{
    [super setUp];
    // Set-up code here.
}

- (void)tearDown
{
    // Tear-down code here.
    [super tearDown];
}  
// Test methods go here
@end

Which is just the basic skeleton. It works fine in my other project, and in this project as long as I don't import any other files. When I do import another file from this project and use it, I see the following error in the Xcode output log:
The test bundle at /Users/[Me]/Library/Developer/Xcode/DerivedData/[AppName]-dwuuuwcpmdqxqmgxomoniplwhlpb/Build/Products/Debug-iphonesimulator/[AppName]Tests.octest could not be loaded because a link error occurred. It is likely that dyld cannot locate a framework framework or library that the the test bundle was linked against, possibly because the framework or library had an incorrect install path at link time.

I've already verified that:

  1. All the frameworks I use have been added to "Link Binary with Libraries" for both the app and test targets.
  2. The test target has been configured to build correctly and that all my test methods show up in Edit Scheme...->Test->Tests
  3. Every issue but this one has been resolved and there are no compiler errors.
  4. All the settings discussed here are set up correctly and identical to my other project that tests correctly.

Any thoughts on what might be causing this?

Principality answered 7/6, 2011 at 16:8 Comment(3)
I am having this EXACT same problem. Tests run fine until you allocate an object from the host application. Been stumped all day :(Almira
@Almira I've been stumped for a good month and a half :P Eventually I just gave up and did testing the old fashioned way. Maybe the new Xcode will fix it, who knows. Do let us know if you find anything, though.Principality
Like many before me I have given up and am now using GHUnit. It took about 10 minutes to set up.Almira
A
13

I had to set the "Test Host" property on the unit test target to $(BUNDLE_LOADER). That solved my problem!

Andrew answered 12/9, 2012 at 18:0 Comment(1)
I didn't have this set, and setting it seemed to do it. It launches the app in the iOS simulator while it runs the tests, which seems odd… but now my tests actually run.Kinase
S
7

I just wasted hours on this and similar errors - turns out I had renamed my main target - attempts to fix this by renaming the relevant variables and by removing the entire DerivedData directory were unsuccessful.

I eventually simply set up a new unit test target following the steps here: http://twobitlabs.com/2011/06/adding-ocunit-to-an-existing-ios-project-with-xcode-4/

And everything is fine now.

So - if you have strange, inexplicable link errors you might be better off just creating a new unit test target. Only takes 2 minutes.

Sada answered 3/3, 2012 at 17:53 Comment(2)
I'll have to try that should I ever get back to that project/platform again.Principality
Thanks! I wasted hours too, and eventually this simple solution worked for me.Ruelle
C
7

I did the following:
http://twobitlabs.com/2011/06/adding-ocunit-to-an-existing-ios-project-with-xcode-4/

Take a deeper look at Test_Hosts = $(BUNDLE_LOADER)

Setting the Test_Hosts fixed exactly the same issue!

Carnarvon answered 2/10, 2012 at 15:30 Comment(4)
Excellent link. Really valuable info.Jotham
Double quotes around my TEST_HOSTS path failed, single quotes around my TEST_HOSTS path failed, NO quotes work. Incidentally, there are no spaces in that path in my system.Jeanne
Reading this article solved my problem. The the Build Settings tab should have the Bundle Loader setting set to your app name: $(BUILT_PRODUCTS_DIR)/MyExistingApp.app/MyExistingAppEyeglass
That helped me setup a test target in XCode 5 too, the thing xcode did not do for me, which was causing issues once I tried to test my app's code, was the last step there, the Symbols Hidden by Default needs to be NO in the main app target.Fancyfree
E
4

When I get linker errors running unit tests, two things fix the problem for me. The first solution is to set the Test After Build build setting to YES and choose Product > Build For > Build For Testing to run the tests. This solution is the easier one to implement.

The second solution is to add the application's implementation files to the unit test target. Open the file inspector by choosing View > Utilities > File Inspector. Select an implementation file in the project navigator. Select the checkbox next to the unit test target in the file inspector.

For iPhone applications running in the simulator, make sure the Test Host build setting is blank. The simulator does not support application-hosted unit tests.

Echovirus answered 7/6, 2011 at 18:47 Comment(4)
Thanks for the advice, but unfortunately neither of these techniques fixed the issue. Both ultimately ended up with the same linker error as before. I suppose it might be time to consider alternatives...Principality
@Kongress... If this answer did not work, then why did you accept it? Also, did you ever find a solution?Humoresque
@Humoresque The question has sat for weeks and this was the only response I got. Although it did not fix my specific problem, it was thorough and helpful. From the SO FAQ: "When you have decided which answer is the most helpful to you, mark it as the accepted answer..." There is no clear guideline on how long to wait for this, so I took the initiative. If I handled this wrong, please let me know for future reference.Principality
@Kongress... Accepting answers happens purely at your discretion. I had a similar question, and found yours when searching. Because it has an "accepted" answer, I assumed the issue was resolved. For myself, I only accept an answer when it solves the problem, to alert others to the fact that the question is still open. Once, I received a correct answer 2 months later, and I think the person may not have bothered had I accepted a non-working answer. Let me reiterate, that accepting and up voting are entirely at your discretion. I asked in hopes that you really had found a solution.Humoresque
F
1

I had this same problem once. For some reason one of the source files for my project was also included to be compiled for the test target, which causes this link error.

By making sure that only the test-implementation files are compiled, you should be able to resolve this error. You can check this at:

TestTarget -> Build Phases -> Compile Sources

Flophouse answered 20/1, 2012 at 12:28 Comment(2)
Excellent answer. This fixed a problem I was having with compilation of a unit test bundle.Solidify
I had to take the just the opposite direction: the linker error disappeared only after I added all the source files in the project to the test target. Removing a any source file from the target makes the linker error reappear.Milliemillieme
L
1

Came across this error running Xcode 4.5.2 - it's Nov 2012 - none of the above worked. It seems that setting the bundle loader and test host is supposed to fill in all the dependencies from your project for you - or run the tests in your app's environment or something, but unfortunately wasn't working for me. What it did do was prevent the specific Xcode warnings about which files/libraries were missing.

What worked for me was adding a new target: cocoa touch unit test, (making sure the bundle loader and test host build settings were empty), watching the build errors and manually adding in the missing dependencies - one by one all the source files from my project that were needed and then the Frameworks. Not very elegant but I was just happy to get it working. Not sure why I haven't tried this GHUnit library yet.

Loutish answered 20/11, 2012 at 5:1 Comment(0)
W
0

Make sure that the test target has the app target configured as a dependency (Build Phases -> Target Dependencies).

Wintertime answered 21/6, 2011 at 0:20 Comment(0)
I
0

I'm aware that this question is quite old, but I just struggled with identical issue for some time and finally managed to solve it, so let me share what I found.

I've been porting an app from iOS to Mac, the project itself was created for iOS so both the project and main target had iOS in supported platforms. Now, when I started porting I created new target for Mac, and changed supported platforms to OSX only for that target. After that I created another target for unit tests, but forgot to change the supported platforms from iOS to Mac. I think you already should know what the problem was, basically the unit tests target is by default linked with Cocoa framework so since the supported platforms for this target was only iOS the cocoa framework was never built and wasn't properly linked. Changing supported platforms to OSX for the test target fixed the problem.

I'm aware that this may not be very helpful for iOS test targets, but at least go to your test target Link Binary With Libraries section and see if there are any red libraries. This gave me the idea, maybe it will also help some of you.

Inexpedient answered 7/9, 2012 at 15:7 Comment(0)
M
0

I've run into this after several merges lately where a coworker and I have both added files to the project, and not all of the implementation files are a member of the unit testing target.

The solution:

  1. Select a small range of your .m files (use "Filter in Navigator" (cmd-opt-j) to search for .m)
  2. Show File Inspector (cmd-opt-1) to view the files' target memberships
  3. Make sure the appropriate files are a member of your test target.

Note: if the test target checkbox shows - instead of + or being unchecked, it means that some, but not all, of the selected files are a member of the target.

I've tried doing more intelligent things at merge time with the .xcodeproj's project.pbxproj file, but I've given up out of frustration with its inscrutability every time and fallen back on this method.

(Another note: I only select a few files at a time for two reasons:

  • Xcode's performance for the file inspector when selecting more than 7–10 files is poor
  • Some files aren't and shouldn't be a member of the test target, and it's easier to do a process of elimination when the selected range is small)
Maltreat answered 27/6, 2013 at 20:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.