150

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

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

我可以毫无问题地针对不使用 CocoaPods 库的类运行单元测试。

我要解决这个问题了吗?我应该做其他事情来让编译器看到 CocoaPods 库吗?

4

14 回答 14

225

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 答案

您要使用的内容link_with来自您的Podfile. 就像是:

link_with 'MainTarget', 'MainTargetTests'

然后pod install再次运行。

于 2013-07-26T16:00:22.067 回答
174

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

如果您在项目导航器中查看您的项目并单击信息选项卡,您将在顶部看到您的构建配置。如果您为不同的配置打开显示三角形,您将看到主要目标下列出的 Pod。我还必须单击下拉菜单并将 Pod 添加到逻辑测试目标。

配置快照

我还必须复制我的主要目标的设置$(inherited)并将${PODS_HEADERS_SEARCH_PATHS}它们复制到构建设置/HEADER_SEARCH_PATHS 下的逻辑测试目标。

最后,我必须在 Link Binary with Libraries 构建阶段为我的逻辑测试目标添加 libPods.a。

希望这能够帮助别人。

于 2013-01-25T02:58:22.703 回答
53

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

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

在此处输入图像描述

于 2013-05-21T08:12:31.467 回答
18

我同意其他答案,即有必要将库链接到测试目标。然而,到目前为止,没有任何建议对我有帮助。正如@fabb 在评论中所写:“在测试时,isSubclassOfClass:调用返回 NO,它们应该返回 YES。我可以解释的唯一原因是依赖项确实链接到主目标和测试目标,以及当测试目标的包loader 加载主包,它无法决定采用哪个类。” 我对这个线程中所有以前的建议都遇到了同样的问题。

我开始工作的解决方案是更新我的 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 不会在我的项目中插入必要的链接逻辑。

这个链接帮助我得出这个结论。

于 2014-11-27T07:19:51.307 回答
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,这在应用程序测试目标中是合理的,但它会导致逻辑测试目标中的链接器错误。

于 2014-12-01T06:26:39.210 回答
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”添加到两个目标,而“Typhoon”仅添加到“MyProject”目标

于 2015-01-21T21:30:57.020 回答
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 组中)

于 2014-07-25T12:59:30.073 回答
4

当我在某些版本控制期间丢失了一些库文件时,我也遇到了类似的情况。我仍然在我的 Pod 中看到了库文件,但是由于缺少实际代码,XCode 说它已经消失了。令我沮丧的是,运行“pod install”并没有立即恢复丢失的文件。

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

  1. 从 Podfile 中删除库
  2. 运行“pod install”以完全删除库
  3. 将库放回 Podfile
  4. 再次运行“pod install”

这应该使图书馆恢复其原始形式。

于 2014-03-05T16:54:44.070 回答
2

还值得注意的是,如果你libPods.a添加了两次,你会得到一些像这样的讨厌的错误:

232 duplicate symbols for architecture i386

要修复它,只需删除libPods.aProject Explorer 中的一个引用。

于 2013-04-16T00:56:57.600 回答
2

试试这个它对我有用,

我们需要在 Configurations 中设置 Pod,

Xcode 项目(您的项目)中的 Project->Info->Configurations应设置为主项目“Pods”以进行调试、发布(以及您拥有的其他内容)。请参阅“未找到标题 - 不包括搜索路径”

在此处输入图像描述

希望这对某人有所帮助。

于 2018-09-12T12:06:05.047 回答
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 目标可以访问应用程序目标的依赖项,而无需多个二进制副本。这大大加快了我的测试构建时间。

于 2016-11-29T13:16:53.857 回答
1

我正在使用我的 Swift 应用程序在 iOS 上使用 GoogleMaps Objective-C POD 集成,因此对我来说,问题是测试目标在构建设置中没有对桥头文件 ( SWIFT_OBJC_BRIDGING_HEADER ) 的引用。确保您的应用程序和测试应用程序目标都指向该目标,以便可以在 swift 单元测试中使用第 3 方 API 调用(地图 API 等)。

于 2015-08-27T20:37:59.567 回答
0

我在 XCTest 下使用 OpenCV 时遇到问题。它给了我Undefined symbols for architecture arm64cv::Mat. 我正在使用pod 'OpenCV', '~> 2.0'主要目标下通过 CocoaPods 安装 OpenCV。无论我多么努力地将 OpenCV 依赖项放在测试目标下或使用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它有助于清理项目并确保您在测试时重新开始。您可以使用[sudo] gem install cocoapods-deintegrate cocoapods-clean.

于 2019-02-10T18:38:38.343 回答
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

如果没有这个,我在测试运行时会收到有关重复符号的警告。

在此警告消失后。

于 2017-04-14T02:57:45.593 回答