使用带有iOS逻辑测试的CocoaPods时找不到库

时间:2013-01-24 23:32:03

标签: ios unit-testing cocoapods

我正在尝试针对我的项目中的类编写一些iOS逻辑测试,这些类使用podspec中某些库的功能。我正在使用Xcode中提供的标准单元测试包(尽管不是应用程序测试,只是单元测试)。

例如,我使用魔法记录,我在podspec中链接了该库。它存在于我的工作区中的Pods项目中,并且当应用程序在模拟器或设备上运行时,可以按预期工作。当我尝试链接到测试使用Magical Record的对象时,我得到一个链接器错误,指出它无法从Magical Record中找到选择器。我已经尝试在我的逻辑测试包中更新我的HEADER_SEARCH_PATH,甚至将其硬编码到CocoaPods创建的headers目录中,但没有运气。

我可以针对没有使用CocoaPods库的类运行单元测试。

我是不是错了?我是否应该做其他事情让编译器看到CocoaPods库?

14 个答案:

答案 0 :(得分:224)

CocoaPods 1.0已经改变了这个的语法。它现在看起来像这样:

def shared_pods
    pod 'SSKeychain', '~> 0.1.4'
    ...
end

target 'Sail' do
    shared_pods
end

target 'Sail-iOS' do
    shared_pods
end

Pre CocoaPods 1.0回答

您要使用的是来自Podfile的{​​{3}}。类似的东西:

link_with 'MainTarget', 'MainTargetTests'

然后再次运行pod install

答案 1 :(得分:174)

通过查看我的应用程序的主要目标是如何从CocoaPods库接收设置,我想出了这个。 CocoaPods包含一个名为Pods.xcconfig的.xcconfig文件。该文件包含所有标题搜索路径。

如果您在项目导航器中查看项目并单击“信息”选项卡,您将在顶部显示您的构建配置。如果您打开不同配置的显示三角形,您将在主目标下看到Pods。我不得不点击下拉菜单并将Pods添加到逻辑测试目标。

Configurations Snapshot

我还必须从主目标中复制$(inherited)${PODS_HEADERS_SEARCH_PATHS}的设置,然后将它们复制到Build Settings / HEADER_SEARCH_PATHS下的逻辑测试目标。

最后,我必须在链接二进制文件中添加libPods.a,并为我的逻辑测试目标添加库构建阶段。

希望这能够帮助别人。

答案 2 :(得分:53)

我在这里找到了一个解决方案Unit Tests With CocoaPods

在Xcode中打开项目文件,然后选择Project(而不是目标),在右侧面板中,有一个名为Configurations的部分。在测试目标的“基于配置文件”列中选择“窗格”。

enter image description here

答案 3 :(得分:18)

我同意其他答案,说明有必要将库链接到测试目标。但是到目前为止,没有任何建议对我有帮助。正如@fabb在评论中写道:“在测试时,isSubclassOfClass:调用返回NO,它们应该返回YES。我可以解释这个的唯一原因是依赖关系真正链接到main和test目标,并且当测试目标的bundle loader加载主bundle时,它无法决定采用哪个类。“我在此主题中遇到了所有先前建议的相同问题。

我开始使用的解决方案是更新我的Podfile,为我的主目标和我的测试目标定义特定的Pod:

target 'MyTarget' do
   pod 'AFNetworking', '~> 2.5.0'
   pod 'Mantle', '~> 1.5'
end

target 'MyTargetTests' do
   pod 'OCMockito', '~> 1.3.1'
end

为我的测试目标指定Pod是必要的,即使我没有使用任何特定于测试的Pod。否则CocoaPods不会在我的项目中插入必要的链接逻辑。

This link帮助我得出了这个结论。

答案 4 :(得分:6)

我添加了:exclusive => true以避免应用程序测试目标中出现重复的符号错误。

target 'myProjectTests', :exclusive => true do
   pod 'OCMock', :head
   pod 'XCTAsyncTestCase', :git => 'https://github.com/iheartradio/xctest-additions.git'
end

link_with 'myProject', 'myProjectTests'

当我将应用程序测试目标更改为逻辑单元测试目标时,会发生链接器错误。 删除:exclusive => true后,一切都会重新运作。

target 'myProjectTests', do
   pod 'OCMock', :head
   pod 'XCTAsyncTestCase', :git => 'https://github.com/iheartradio/xctest-additions.git'
end

link_with 'myProject', 'myProjectTests'

:exclusive => true声明do...end之外的所有内容都不应该链接到myProjectTests,这在应用程序测试目标中是合理的,但它会导致逻辑测试目标中的链接器错误。

答案 5 :(得分:6)

您可以根据@Keith Smiley解决方案使用link_with。

如果你有共同的pod和每个目标的细节,你可能想要使用" def"用于定义pod组的选项。并使用" def"后来在独家目标。

def import_pods
    pod 'SSKeychain'
end

target 'MyProjectTests', :exclusive => true do
  import_pods
end

target 'MyProject', :exclusive => true do
  import_pods
  pod 'Typhoon'
end

在上面的示例中,我添加了SSKeychain'对于这两个目标,和“台风”#39;仅限于MyProject'目标

答案 6 :(得分:5)

我对此问题的解决方案是更改我的Podfile以将库包含在这两个目标中

target "MyApp" do  
    pod 'GRMustache', '~> 7.0.2'
end

target "MyAppTests" do
    pod 'GRMustache', '~> 7.0.2'
end

由于我使用的是swift,我还必须配置测试目标以包含MyApp-Bridging-Header.h文件。 (在Build Settings选项卡下的Swift Compiler组中)

答案 7 :(得分:4)

当我在某些版本控制期间丢失了一些库文件时,我遇到了类似的情况。我仍然在我的Pods中看到了库文件,但实际代码丢失了,XCode说它已经不见了。令我沮丧的是,运行'pod install'并没有立即将丢失的文件带回来。

我必须通过执行以下操作手动删除并更换pod:

  1. 从Podfile中删除库
  2. 运行'pod install'以完全删除库
  3. 将库放回Podfile
  4. 再次运行'pod install'
  5. 这应该将库置于其原始形式中。

答案 8 :(得分:2)

还值得注意的是,如果你有libPods.a两次添加,你会得到一些令人讨厌的错误:

232 duplicate symbols for architecture i386

要解决此问题,只需在Project Explorer中删除其中一个libPods.a引用。

答案 9 :(得分:2)

从CocoaPods 1.x开始,有一种新方法可以声明目标与相应测试目标之间的共享依赖关系。我一直在使用Mark Struzinski接受的解决方案,但在运行我的测试时,使用这种方法产生了大量的警告:

Class SomeClass is implemented in both /Path/To/Test/Target and /Path/To/App/Target. One of the two will be used. Which one is undefined.

使用CocoaPods 1.x,我们可以将-Test目标声明为通过父目标的搜索路径继承,如下所示:

target 'MyApp' do
    pod 'aPod'
    pod 'anotherPod'
    project 'MyApp.xcodeproj'
end
target 'MyAppTests' do
    inherit! :search_paths
    project 'MyApp.xcodeproj'
end

这将导致-Test目标可以访问应用程序目标的依赖项,而无需多个二进制副本。这严重加快了我的测试构建时间。

答案 10 :(得分:2)

尝试一下,这对我有用,

我们需要在配置中设置Pod,

Xcode项目(您的项目)中的

Project-> Info-> Configurations (项目->信息->配置)应设置为主要项目“ Pods”,以进行Debug,Release(以及其他功能)。参见"Headers not found – search paths not included"

enter image description here

希望这对某些人有帮助。

答案 11 :(得分:1)

我正在使用我的Swift应用程序在iOS上使用GoogleMaps Objective-C POD集成,所以对我来说问题是测试目标没有对Bridge Header文件的引用( SWIFT_OBJC_BRIDGING_HEADER )在构建设置中。确保您的应用和测试应用目标都指向这一点,以便第三方API调用(地图API等)可用于快速单元测试。

答案 12 :(得分:0)

下一个语法为我提供了最好的结果(在cocoapod v.1.2.1下测试):

https://github.com/CocoaPods/CocoaPods/issues/4626#issuecomment-210402349

 target 'App' do
    pod 'GoogleAnalytics' , '~> 3.0'
    pod 'GoogleTagManager' , '~> 3.0'

     pod 'SDWebImage', '~>3.7'
     platform :ios, '8.0'
     use_frameworks!

     target 'App Unit Tests' do
         inherit! :search_paths
     end
 end

如果没有这个,我会在测试重复符号时发出警告。

此警告消失后。

答案 13 :(得分:0)

在XCTest下使用OpenCV时遇到问题。对于einsum之类的类,这给了我Undefined symbols for architecture arm64的链接器错误。我正在主要目标下使用cv::Mat通过CocoaPods安装OpenCV。无论我多么努力地将OpenCV依赖项置于测试目标之下,或者使用pod 'OpenCV', '~> 2.0'都无济于事。解决方案是像这样创建inherit! :search_paths

abstract_target

# Uncomment the next line to define a global platform for your project platform :ios, '6.1.6' abstract_target 'Shows' do pod 'RMVision', path: '../..' pod 'RMShared', path: '../../../RMShared' pod 'OpenCV', '~> 2.0' target 'RMVisionSample' do # Uncomment the next line if you're using Swift or would like to use dynamic frameworks # use_frameworks! # Pods for RMVisionSample end target 'RMVisionSampleTests' do # inherit! :search_paths # Pods for testing end target 'RMVisionBenchmarks' do # inherit! :search_paths # Pods for testing end end pod deintegrate命令也很有用,它们有助于清理项目并确保在测试时重新开始。您可以使用pod clean安装这两个。