我正在尝试针对我的项目中的类编写一些iOS逻辑测试,这些类使用podspec中某些库的功能。我正在使用Xcode中提供的标准单元测试包(尽管不是应用程序测试,只是单元测试)。
例如,我使用魔法记录,我在podspec中链接了该库。它存在于我的工作区中的Pods项目中,并且当应用程序在模拟器或设备上运行时,可以按预期工作。当我尝试链接到测试使用Magical Record的对象时,我得到一个链接器错误,指出它无法从Magical Record中找到选择器。我已经尝试在我的逻辑测试包中更新我的HEADER_SEARCH_PATH,甚至将其硬编码到CocoaPods创建的headers目录中,但没有运气。
我可以针对没有使用CocoaPods库的类运行单元测试。
我是不是错了?我是否应该做其他事情让编译器看到CocoaPods库?
答案 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添加到逻辑测试目标。
我还必须从主目标中复制$(inherited)
和${PODS_HEADERS_SEARCH_PATHS}
的设置,然后将它们复制到Build Settings / HEADER_SEARCH_PATHS下的逻辑测试目标。
最后,我必须在链接二进制文件中添加libPods.a,并为我的逻辑测试目标添加库构建阶段。
希望这能够帮助别人。
答案 2 :(得分:53)
我在这里找到了一个解决方案Unit Tests With CocoaPods:
在Xcode中打开项目文件,然后选择Project(而不是目标),在右侧面板中,有一个名为Configurations的部分。在测试目标的“基于配置文件”列中选择“窗格”。
答案 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:
这应该将库置于其原始形式中。
答案 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"
希望这对某些人有帮助。
答案 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
安装这两个。