UPDATE: I ended up giving up and added GHUnit to my project instead. I got up and running with GHUnit in a matter of minutes.
UPDATE: You can download the Xcode project here: http://github.com/d11wtq/Cioccolata
I've added a Unit Test target to my Xcode project but it fails to find my framework when it builds, saying:
Test.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.
My framework (the main project target) is designed to be embedded and so has an install path of @executable_path/../Frameworks
.
I've marked the framework as a direct dependency of the test target and I've added it to the "Link Binary with Libraries" build phase.
Additionally I've add a first step (after it's built the dependency) of "Copy Files" which simply copies the framework to the unit test bundle's Frameworks directory.
Anyone got any experience on this? I'm not sure what I've missed.
EDIT | I'm pretty sure I'm not supposed to, since a framework is not executable, but I haven't set "Test Host" and "Bundle Loader". This should (to my understanding) all be ok since the test bundle is linked against the framework and will load it just like any other bundle.
EDIT | I think I'm nearly there. I read the following article which dictates the use of @rpath instead of @executable_path.
http://www.dribin.org/dave/blog/archives/2009/11/15/rpath/
In this case it makes perfect sense since the OCUnit test bundle is NOT an executable, it's a plain old bundle, so @executable_path is not compatible. So now my framework has its installation directory set to @rpath
and the Test target has its runtime search paths (rpath) defined as the build directory. This saves me having to copy the framework into the test bundle and means that overall the resulting framework is much more flexible in nature since it can live anywhere.
Now, I also realize that I should have set the Bundle Loader on the Test target, so this is now set to the path of the framework binary.
I can build the test target and I can #import classes from the framework, error free. But as soon as I try to instantiate a class from the framework I get the following error:
/Developer/Tools/RunPlatformUnitTests.inclu开发者_运维问答de:412: note: Started tests for architectures 'i386'
/Developer/Tools/RunPlatformUnitTests.include:419: note: Running tests for architecture 'i386' (GC OFF)
objc[50676]: GC: forcing GC OFF because OBJC_DISABLE_GC is set
Test Suite '/Users/chris/Projects/Mac/Cioccolata/build/Debug/Test.octest(Tests)' started at 2010-05-21 12:53:00 +1000
Test Suite 'CTRequestTest' started at 2010-05-21 12:53:00 +1000
Test Case '-[CTRequestTest testNothing]' started.
/Developer/Tools/RunPlatformUnitTests.include: line 415: 50676 Bus error "${THIN_TEST_RIG}" "${OTHER_TEST_FLAGS}" "${TEST_BUNDLE_PATH}"
/Developer/Tools/RunPlatformUnitTests.include:451: error: Test rig '/Developer/Tools/otest' exited abnormally with code 138 (it may have crashed).
Command /bin/sh failed with exit code 1
My test method does nothing more than allocate and subsequently release a HelloWorld class I created to help debug this setup:
- (void)testNothing {
CTHelloWorld *h = [[CTHelloWorld alloc] init];
[h release];
}
If I replace these lines of code with an STAssertTrue(YES, @"Testing nothing");
the error goes away, even though the class is still being imported.
Since nobody else has chimed into this question, I'll finish off by saying SenTestingKit really unimpressed me with the complexity (and ugliness) of the setup for my needs. I highly recommend GHUnit which runs in a UI (or on command line if you prefer) and supports using gdb out of the box. It took me a matter of minutes to download and use GHUnit in my project.
It's pretty too. Apple should ship it with Xcode instead of SenTestingKit IMHO.
I had the same problem but with Kiwi Unit Testing framework. My problem was that "Test Host" was not set under Build Settings. When I set it to $(BUNDLE_LOADER) everything worked perfectly. Verified using Xcode 4.5.2 iOS SDK 6.0.
It happened to me a few times. I know you switched to GHUnit, but just in case someone is interested: after going around this for a LONG time I realised that Xcode just didn't add the code classes (.m files) in the Compile part of the target, but in the Copy Resources part of the target. Moving it to the right place solved the issue.
You might have some luck with the following article, in particular adding DYLD_FRAMEWORK_PATH and DYLD_LIBRARY_PATH to your executable might help.
Ok, so I too fought with this, and here is what I have found to be the simple solution to the problem:
- Create your application/framework
- Create your test bundle "additional target", do not set a dependency on your main
- Drag the files you want to test from your classes to the "compile sources" of your test bundle target
- Create your test cases, adding them only to the test bundle target
- compile test target, tests run.
Note, this means you simply have to compile your test bundle target when you want to run your tests. Ideal, no; works, yes.
Apple really automate this and get it working correctly, out of the box.
I do agree with the recommendations for GHUnit, it totally rocks!
However, I've switched to using OCTest after Apple integrated it in xCode4 so I'm trudging through the issues.
The linking problem reported here occurred for me after we added new files to the project. These included ViewControllers and xibs but the files were marked in xcode for both the application and the test target. I discovered the files by inspecting the OCTest bundle in the derived data directory. ~/Library/Developer/Xcode/DerivedData/ Right click and choose "Show Package Contents" from finder. Look for stuff that does not belong there, ie: application classes and resources. Removing these files from the "Compile Sources" or "Copy Bundle Resources" corrected the linking error.
精彩评论