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.include: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.