使用Cocoapods进行Xcode单元测试

140

这几天我一直在苦苦思索,但是尽管进行了多次谷歌/ Stack Overflow / Github 搜索,我仍然找不到解决我遇到的问题的方法!

我所努力做的只是为我的应用程序创建一些使用 Firebase pods 的单元测试。

我正在使用 Xcode 7.3.1 和 Cocoapods 1.0.1。更新:问题仍然存在于 Xcode 8.0。

这是我的 podfile 内容:

platform :ios, '9.0'
use_frameworks!
inhibit_all_warnings!

target 'MyApp' do
    pod 'Firebase'
    pod 'Firebase/Auth'
    pod 'Firebase/Database'
    pod 'Firebase/Storage'

    target 'MyAppTests' do
        inherit! :search_paths
    end
end

在我的 XCTest 类中,我遇到了

缺少所需的模块 "Firebase"

出现错误的位置为 @testable import MyApp

或者使用这个 podfile:

platform :ios, '9.0'
use_frameworks!
inhibit_all_warnings!

def common_pods
    pod 'SwiftyTimer'
    pod 'Firebase'
    pod 'Firebase/Auth'
    pod 'Firebase/Database'
    pod 'Firebase/Storage'
end

target 'MyApp' do
    common_pods
end

target 'MyAppTests' do
    common_pods
end

测试已经构建完成,但我的控制台上充斥着警告信息,例如:

类<-FirebaseClassName->在...MyApp...和...MyAppTests...中都有实现。将使用其中之一,哪一个是未定义的。


我之前只使用Firebase Analytics。但是转换到Google Analytics后,一切都非常顺利。 - marosoaie
我自己还没有尝试过,但我可能会尝试手动包含 Firebase 而不使用 CocoaPods:https://firebase.google.com/docs/ios/setup#frameworks - Jonny
1
这仍然是一个问题。 - Edward
14个回答

96

我曾经遇到过同样的问题。通过将 pod 'Firebase' 移动到我的测试目标中,我解决了这个问题。请将您的 Podfile 更改为以下内容:

platform :ios, '9.0'
use_frameworks!
inhibit_all_warnings!

target 'MyApp' do
    pod 'Firebase/Auth'
    pod 'Firebase/Database'
    pod 'Firebase/Storage'

    target 'MyAppTests' do
        inherit! :search_paths
        pod 'Firebase'
    end
end

1
谢谢,但我刚刚尝试了那个方法,仍然存在“Class ... is implemented in both ... ”的问题。 - doovers
1
它对我起作用了,但我仍然不明白。这已经不是我第一次发现Firebase设置他们的podspecs很奇怪了,参见https://twitter.com/dirtyhenry/status/836240557311684608,但Firebase团队没有回复:( - Dirty Henry
5
我做出这个更改后,并没有立即消除警告,但在我运行pod install之后问题得到了解决。 - blwinters
1
问题解决了一半。另一半是在“构建设置”->“头文件搜索路径”下,仅将"${PODS_ROOT}/Firebase/Core/Sources"添加到您的测试目标中。 - ArgaPK
在进行这个更改后,不要忘记运行“pod install”来更新项目依赖项 ;) - jawad
@Mackarous,我们如何使用“Swift Package Manager”实现类似的功能? - Saif

63

尝试将继承方式更改为:complete,如下所示:

target 'MyAppTests' do
    inherit! :complete
end

重要的是,它允许任何查看您的repo的其他人像往常一样执行pod update,而无需复制.xcconfig文件或其他hackery即可构建。

(Note: This is the same content, but in Chinese.)

1
这也有“Class ... 在...中被实现”的问题。 - Diogo T
它消除了编译时的错误,但在运行时引起了这个错误:clang: error: linker command failed with exit code 1 (use -v to see invocation)。 - CMont
{btsdaf} - smapps

61
  1. 选择您的单元测试目标设置。
  2. 进入构建设置。
  3. 找到头文件搜索路径。
  4. 添加这个值 $(SRCROOT)/Pods 并勾选递归,然后 Xcode 将为您解析路径。

这是示例


1
谢谢@Kanika Sharma - Rahul K Rajan

35
问题在于Firebase在CocoaPods生成设置中的Header Search Paths上进行了特殊处理,因此CocoaPods没有意识到这种变化,无法将其传递到测试目标中。您可以有两种方式解决这个问题:
  1. 在文件导航器中找到 MyAppTests.<configuration>.xcconfig,并将以下内容添加到 HEADER_SEARCH_PATHS 中:

    ${PODS_ROOT}/Firebase/Analytics/Sources [*]

  2. 在Build Settings中找到 Header Search Paths 设置,并将第一种选项中相同的值添加到列表中,您不需要将其设置为递归。

* 根据AKM的评论,从版本3.14.0开始更改为${PODS_ROOT}/Firebase/Core/Sources.


尝试过了,但仍然收到相同的警告。 - doovers
8
截至Firebase 3.14.0,这个解决方案仍然有效,但是补丁已更改为${PODS_ROOT}/Firebase/Core/Sources - AKM
1
新路径对我也起作用了!我正在运行CocoaPods 版本1.2.0,但请记住我还必须在Podfile中的测试目标中添加inherit! :search_paths - Paulo Mattos
  1. 对我不起作用。使用的是 Firebase 3.x (不是最新的 4.x)。
- Jonny
问题可以在此处跟踪:https://github.com/firebase/firebase-ios-sdk/issues/58 - CMont
完成了一半的问题,在另一半中将'Firebase'添加到测试目标中。 - ArgaPK

10
${SRCROOT}/Pods/Firebase/CoreOnly/Sources添加到单元测试目标的“头文件搜索路径”中可以解决问题。 步骤: 1. 选择您的单元测试目标 2. 进入“构建设置” 3. 搜索“头文件搜索路径” 4. 添加${SRCROOT}/Pods/Firebase/CoreOnly/Sources

enter image description here

接下来测试可以运行,错误将消失。

这是对我有效的方法。不需要修改podfile或xcconfig文件。感谢分享。 - Saran

9

在我能够使这个工作之前,需要进行三个步骤:

CocoaPods版本:1.5.0 Swift版本:4 Firebase版本:4.13.0

步骤1: 请确保将以下目标块添加到您的podfile中。

# Uncomment the next line to define a global platform for your project
platform :ios, '11.3'

target 'TIMII' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!

# Pods for TIMII
pod 'Firebase/Core'
pod 'Firebase/Database'
pod 'Firebase/Auth'
pod 'Firebase/Storage'

    target 'TIMIITests' do
        inherit! :search_paths
        pod 'Firebase/Core'
    end

end

步骤2: 在YourAppTests项目导航器的构建设置选项卡中,找到“Header Search Path”行,并在Debug下添加以下行: $(inherited) ${PODS_ROOT}/Firebase/Core/Sources
步骤3: 在终端中运行: pod update

除非您明确想要更新您的pods,否则请优先使用pod install而不是pod update。 文档:https://guides.cocoapods.org/using/pod-install-vs-update.html - Sam
这个回答真的帮了我很多。谢谢。这篇帖子中的其他方法对我没有起作用。 - DJ-Glock

8
一种更简单的方法也能达到同样的效果:
target 'MyApp' do
    pod 'Firebase/Auth'
    pod 'Firebase/Database'
    pod 'Firebase/Storage'

    target :MyAppTests
end

1
这个完美地运行了。谢谢。有关语法的任何文档?“:MyAppTests”是什么意思? - Tim Chen
这对我也有效,而且语法看起来最简单! - Bruce

7
这个问题已记录在Firebase项目中:

https://github.com/firebase/firebase-ios-sdk/issues/58

有一个解决方法:

仅在“构建设置”->“头搜索路径”下,将"${PODS_ROOT}/Firebase/Core/Sources"添加到您的测试目标中

但是,通过升级到CocoaPods 1.4.0或更高版本,也可以解决此问题,这是更好的解决方案。

在我写这篇文章时(2017年11月),cocoapods 1.4.0仍处于beta版本,因此要安装它,您需要明确请求beta:

gem install cocoapods --pre

这样做,然后执行pod install解决了运行测试的问题。


1
"PODS_ROOT" 是什么意思? - ArgaPK
@ArgaPK 这是CocoaPods设置的一个变量。只需将我在""之间写的内容粘贴到Xcode中即可。实际上,最好的方法是将您的CocoaPods升级到>= 1.4.0版本。 - JosephH
1
@JosephH,不幸的是,将我的CocoaPods更新到1.5.2并没有解决问题。 - Stacy Smith
@AnastasiaKovaleva 在升级后是否运行了 pod install - JosephH
@JosephH 运行 pod install 解决了我的问题!非常感谢! - Stacy Smith

5

我尝试了上面的所有方法,但遇到了各种不同的错误,最初出现了 缺少必需的模块“Firebase”,然后如果我尝试将 Firebase Pods 添加到我的测试目标中,就会出现 "Class ... is implemented in both ... " 或链接器问题。

对我有效的解决方案是:

  1. 从 Podfile 中完全删除测试目标,并运行 'pod update' 以确保 XCode 项目同步。
  2. 打开我的测试目标的 Build Settings 并更新头文件搜索路径,只包括以下 3 个条目:
    • $(inherited) non-recursive
    • $(SRCROOT)/Pods/Headers/Public recursive
    • $(SRCROOT)/Pods/Firebase recursive

此时,清理构建文件夹,重新构建,然后重新运行测试对我有用。希望能对某人有所帮助!


4

对我来说,解决方案是将cocoapods更新到1.1.0.rc.2版本。

sudo gem install cocoapods --pre


不幸的是,它对我不起作用......我必须取消我的点赞! - Zeb
很抱歉这没能帮到你们,不确定为什么它解决了我的问题而没有解决你们的问题... - doovers
我现在使用的是1.20版本,但没有成功。 - UKDataGeek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接