最近我开始对我的应用程序进行单元测试。这个项目(在Xcode4中)是在没有单元测试包的情况下创建的,所以我不得不进行设置。 我已按照此处的步骤操作:http://cocoawithlove.com/2009/12/sample-mac-application-with-complete.html 并且它适用于简单的类,但现在我正在尝试测试一个依赖于另一个和另一个类的类等。
首先我收到了一个链接器错误,所以我将*.m
个文件添加到了测试用例目标中,但是现在我收到了我正在尝试测试的每个类的警告:
Class Foo在两个MyApp中实现 和MyAppTestCase。其中一个会 使用。哪一个未定义。
我想知道为什么会这样?我怎么解决这个问题?也许我在设置单元测试目标时遗漏了什么?
将“Bundle Loader”正确设置为$(BUILT_PRODUCTS_DIR)/AppName.app/AppName
将“默认隐藏的符号”设置为否(在目标应用程序的构建设置中)。这是链接器错误的来源,因为它默认为YES!我一直在努力奋斗这么久!。
答案 0 :(得分:42)
Class Foo在MyApp和MyAppTestCase中实现。将使用两者之一。哪一个未定义。
我想知道为什么会这样?
因为两个图像(应用程序和单元测试包)都定义了类的实现。该类被动态加载到objc运行时。 objc运行时使用平面命名空间。这是如何工作的:
您通常可以通过重命名类或在一个图像中导出类来避免这种情况。重命名该课程显然不适用于您的情况。你有一个文件Foo.m
,当它应该在一个文件中时,它被两个图像编译,导出和加载。
这应该被解释为重复的符号链接器错误。即使实现是相同的源文件(并且实现是相同的) - 这是一个必须修复的问题。
我该如何解决这个问题?
如果Foo.m
是应用程序的类,则必须从单元测试中删除(不编译和链接)Foo.m
。如果它是单元测试的一部分,则不要编译并将其链接到单元测试目标。
然后,按照帖子中的说明将您的单元测试链接/加载到应用程序。它位于帖子的这个一般区域:其中“WhereIsMyMac”是您单元测试的应用程序的名称。这将使测试目标链接到应用程序(因此在编译时不会出现链接器错误)。重要的部分是您的测试文件是在单元测试目标(仅)中编译的,以及您的应用程序的类编译并链接到应用程序。你不能只是添加它们 - 它们动态地链接和加载。
也许我在设置单元测试目标时错过了什么?
来自你链接的文章:
注意:测试目标是一个单独的目标。这意味着您需要注意目标成员资格。应将所有应用程序源文件仅添加到应用程序目标。测试代码文件应仅添加到测试目标中。
你出错的部分可能是单元测试包的链接和加载阶段。
答案 1 :(得分:17)
如果您正在使用Cocoapods,则您的podfile只需要主要目标部分中的依赖项,而不是测试目标。如果您确实为测试目标添加了重复的依赖项,那么您将收到OP的错误消息。
target 'MyProject' do
pod 'Parse'
end
target 'MyProjectTests' do
end
target 'MyProjectUITests' do
end
答案 2 :(得分:12)
对我来说,我需要做的只是取消选中使Foo类成为单元测试目标成员的复选框。它不应该是两个目标的成员,应该如下所示:
如果您看不到图像,则会显示Xcode“目标成员资格”窗格的屏幕截图。有两个目标:一个带有“A”应用程序图标和测试名称。另一个是单元测试目标,并有一个单元测试图标:
Target Membership
[X] Foo
[ ] FooTests
答案 3 :(得分:3)
对我来说,这发生了,因为我已经部署到设备,然后在我启用NSZombies时模拟器。解决方案是切换到模拟器配置&做产品 - >清洁然后切换到设备配置&照着做。错误消失了。它与构建缓存有关。
答案 4 :(得分:2)
原因是您覆盖了在其他目标中定义的App Target的构建设置的k1
。
<强>解决方案:强>
转到您的应用目标并找到
RUNPATH_SEARCH_PATHS
构建设置并使用RUNPATH_SEARCH_PATHS
标记:调试和发布
答案 5 :(得分:0)
遇到相同的问题,我的情况是在/System/Library/Frameworks/Foundation.framework/Foundation中都实现了NSNotification类,是否有任何家伙遇到相同的问题,任何方向或建议都会得到应用。 / p>