Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCUnit testing an embedded framework

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.

like image 254
d11wtq Avatar asked May 19 '10 16:05

d11wtq


Video Answer


2 Answers

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.

like image 106
d11wtq Avatar answered Sep 24 '22 03:09

d11wtq


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.

like image 32
Ciryon Avatar answered Sep 24 '22 03:09

Ciryon