xcodeunit-testingobjective-c++sentestingkitoctest

Unit testing Objective-C++ frameworks with Xcode 4.x


I'm writing a framework using Objective C++ and I am having trouble setting up unit tests for it.

Compiling just the framework target works fine.

But when I tell Xcode to compile and run the test bundle I get:

Ld ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug/TestFrameworkTests.octest/Contents/MacOS/TestFrameworkTests normal x86_64
    cd "~/Projects/TestFramework"
    setenv MACOSX_DEPLOYMENT_TARGET 10.7
    "/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++" -arch x86_64 -bundle -isysroot "/Applications/Xcode 4.5.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk" -L~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug -L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib -F~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug "-F/Applications/Xcode 4.5.app/Contents/Developer/Library/Frameworks" -filelist ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Intermediates/TestFramework.build/Debug/TestFrameworkTests.build/Objects-normal/x86_64/TestFrameworkTests.LinkFileList -mmacosx-version-min=10.7 -v -fobjc-arc -fobjc-link-runtime -fprofile-arcs -stdlib=libc++ -framework SenTestingKit -framework Cocoa -framework TestFramework -o ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug/TestFrameworkTests.octest/Contents/MacOS/TestFrameworkTests

Apple clang version 4.0 (tags/Apple/clang-421.10.48) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.0
Thread model: posix
 "/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -bundle -macosx_version_min 10.7.0 -syslibroot "/Applications/Xcode 4.5.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk" -o ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug/TestFrameworkTests.octest/Contents/MacOS/TestFrameworkTests -L~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug -L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib -filelist ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Intermediates/TestFramework.build/Debug/TestFrameworkTests.build/Objects-normal/x86_64/TestFrameworkTests.LinkFileList -framework SenTestingKit -framework Cocoa -framework TestFramework -force_load "/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_macosx.a" -framework Foundation -lobjc -lc++ "/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/4.0/lib/darwin/libclang_rt.profile_osx.a" -lSystem "/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/4.0/lib/darwin/libclang_rt.osx.a" -F~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug "-F/Applications/Xcode 4.5.app/Contents/Developer/Library/Frameworks"
Undefined symbols for architecture x86_64:
  "Foo::Bar::Bar()", referenced from:
      -[FooBar_Tests testBaz] in FooBar_Tests.o
  "Foo::Bar::baz() const", referenced from:
      -[FooBar_Tests testBaz] in FooBar_Tests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I have:

C++ Language Dialect: c++11
C++ Standard Library: libc++

set on both build targets (framework & test bundle).
And I am of course linking against the framework in my test bundle target.
Furthermore, all framework headers are marked public.
I also tried adding the framework files to the test bundle's target and leaving them out. None of these fixed the problem.

I am a bit puzzled as to what's going wrong here, right now. Any ideas?


This is how my C++ class looks like (kind of):

//FooBar.hh
namespace Foo {
    class Bar {
    public:
        bool baz() const;
    }
}

//FooBar.mm
#import "FooBar.hh"
namespace Foo {
    bool Bar::baz() const {
        return true;
    }
}

And this my test case:

//FooBar_Tests.hh
#import <SenTestingKit/SenTestingKit.h>

@interface FooBar_Tests : SenTestCase

@end

//FooBar_Tests.mm
#import "FooBar_Tests.hh"
#import <TestFramework/FooBar.hh>
//this one fails as well (compiles fine, fails one linkage):
//#import "FooBar.hh"

@implementation FooBar_Tests

- (void)testBaz {
    Foo::Bar bar();
    STAssertEquals(bar.baz(), true, nil);
}

Edit: Split code up into .hh&.mm files. Still getting the same errors though.


Solution

  • I eventually added a new unit test target to my project, enabled C++11 and tried compiling/running it. Success.
    Somehow my original unit test target must have gone bad in regards to C++11. Had compiled just fine before.

    Now it's time to migrate my test cases to the new test bundle, I guess.

    …and I thought I was going mad. Oh well…