Модульное тестирование фреймворков Objective-C++ с Xcode 4.x

Я пишу фреймворк, используя Objective C++, и у меня возникают проблемы при настройке модульных тестов для него.

Компилирование только целевой структуры работает отлично.

Но когда я говорю XCode скомпилировать и запустить тестовый пакет, я получаю:

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)

Я имею:

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

установить на обе цели сборки (фреймворк и тестовый комплект).
И я, конечно, связываюсь с фреймворком в моей целевой группе тестов.
Кроме того, все заголовки фреймворка помечены как общедоступные.
Я также попытался добавить файлы фреймворка к цели тестового пакета и пропустить их. Ни один из них не решил проблему.

Я немного озадачен тем, что происходит здесь и сейчас. Есть идеи?


Вот так выглядит мой класс C++ (вроде):

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

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

И это мой тестовый пример:

//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);
}

Изменить: разделить код на .hh&.mm файлы. Все еще получаю те же ошибки, хотя.

2 ответа

Решение

В конце концов я добавил новый объект модульного тестирования в свой проект, включил C++11 и попытался скомпилировать / запустить его. Успех.
Каким-то образом моя первоначальная цель модульного теста, должно быть, пошла плохо в отношении C++11. Скомпилировал просто отлично раньше.

Теперь пришло время перенести мои тестовые наборы в новый тестовый пакет, я полагаю.

... и я думал, что схожу с ума. Ну что ж…

Одной из возможных проблем является то, что ваши юнит-тесты находятся в заголовочном файле. Заголовочные файлы мало что делают в OCUnit. Вы даже можете избавиться от файла заголовка и поместить весь код теста в файл реализации. Добавьте класс модульного тестирования Objective-C в свой проект, дайте ему расширение.mm и переместите туда код тестового примера. Это решает проблему?

Когда я тестирую код C++ с помощью OCUnit, я обнаруживаю, что мне нужно добавить файлы C++ в моем приложении к цели модульного теста, чтобы избежать ошибок ссылок. Я не уверен, применимо ли это к коду Objective-C++, но это то, что нужно изучить.

Другие вопросы по тегам