Xcode 使用 Cocoapods 进行单元测试

Xcode Unit Testing with Cocoapods

过去几天我一直在用这个问题撞墙,但尽管进行了多次 Google/SO/Github 搜索,我还是找不到解决我遇到的问题的方法!

我想做的就是为我的应用创建一些单元测试,它使用了 Firebase pods。

我正在使用 Xcode 7.3.1 和 Cocoapods 1.0.1。 更新: Xcode 8.0

问题仍然存在

有了这个播客文件:

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 class 中我得到

Missing required module 'Firebase'

错误 @testable import MyApp

或者使用此播客文件:

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

测试成功,但我的控制台上到处都是警告,例如:

Class <-FirebaseClassName-> is implemented in both ...MyApp... and ...MyAppTests... One of the two will be used. Which one is undefined

我遇到了同样的问题。我通过将 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

问题在于,在 CocoaPods 为设置生成自己的值后,Firebase 对 Header 搜索路径做了一些特殊的事情,因此 CocoaPods 不会接受此更改以将其转移到测试中目标。您可以通过以下两种方式解决此问题:

  1. 在文件导航器中找到 MyAppTests.<configuration>.xcconfig 并将以下内容添加到 HEADER_SEARCH_PATHS:

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

  2. 在构建设置中找到 Header 搜索路径 的设置,并将与选项 1 中相同的值添加到列表中。您不需要将其设置为递归。

* 根据 AKM 的评论,这在版本 3.14.0

中更改为 ${PODS_ROOT}/Firebase/Core/Sources

我的解决方案是将 cocoapods 更新到版本 1.1.0.rc.2.

sudo gem install cocoapods --pre

我遇到了类似的问题。根据您的问题,我将 MyApp.<configuration>.xcconfig 文件的内容复制到了 MyAppTests.<configuration>.xcconfig 文件中。我清理并构建了测试,它成功了。

尝试将继承更改为 :complete,如:

target 'MyAppTests' do
    inherit! :complete
end

重要的是,它允许其他任何人检查您的存储库,只需像往常一样执行 pod update,而无需复制 .xcconfig 文件或其他仅用于构建的 hackery。

仅将 "${PODS_ROOT}/Firebase/Core/Sources" 添加到您的测试目标 构建设置 -> Header 搜索路径

问题记录在firebase项目这里:

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

有一个解决方法:

Add "${PODS_ROOT}/Firebase/Core/Sources" to your Tests target only under Build Settings -> Header Search Paths

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

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

gem install cocoapods --pre

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

在我让它工作之前的三个步骤:

CocoaPods:1.5.0 Swift 4 火力地堡:4.13.0

第一步: 确保将以下目标块添加到您的 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 Project Navigator Build Settings 选项卡中。找到 Header Search Path 行并将以下行添加到 Debug

$(inherited) ${PODS_ROOT}/Firebase/Core/Sources

第 3 步: 在终端 运行 中:

pod update

正如 @Will 提到的在安装 CocoaPods 后围绕 Header 搜索路径 的问题。

我有一个包含多个目标的项目,其中 pod 'Firebase' 嵌入到单独的模块中,比方说 MyProject-Shared。 'Podfile' 处的 Firebase pod 仅为 'MyProject-Shared' 目标安装。由于错误无法编译其他想要使用 'MyProject-Shared' 的模块:

'missing required module "Firebase" '

我的技巧是在 each 目标的 Build Settings 处添加以下缺少的 header 搜索路径,引用 Analytics-Framework:

"${PODS_ROOT}/Firebase/CoreOnly/Sources"

请看下图:

希望它能节省您的时间。

  1. Select 您的单元测试目标设置。
  2. 转到构建设置。
  3. 寻找 Header 个搜索路径。
  4. 递归添加此值$(SRCROOT)/Pods,然后Xcode将为您解析路径。

这里是Example

我尝试了上述所有方法,运行 遇到了各种不同的错误,最初是从 Missing required module 'Firebase' 开始,然后如果我尝试添加 Firebase Pods 则出现 "Class ... is implemented in both ... " 或链接器问题] 到我的测试目标。

对我有用的解决方案是:

  1. 从 Podfile 和 运行 'pod update' 中完全删除测试目标以确保 XCode 项目同步。
  2. 打开我的测试目标的构建设置并更新 header 搜索路径以仅包含以下 3 项:
    • $(inherited) non-recursive
    • $(SRCROOT)/Pods/Headers/Public recursive
    • $(SRCROOT)/Pods/Firebase recursive

此时清理构建文件夹,re-building 然后 re-running 测试对我有效。希望这对某人有所帮助!

${SRCROOT}/Pods/Firebase/CoreOnly/Sources 添加到单元测试目标的 "Header search paths" 中解决了这个问题。 步骤:

  1. Select 您的 单元测试目标
  2. 转到构建设置
  3. 搜索 header 搜索路径
  4. 添加${SRCROOT}/Pods/Firebase/CoreOnly/Sources

此后测试可以 运行 并且错误将消失。

Missing required module Firebase 没有 CocoaPods 解决方案

对于那些遇到同样问题但没有使用 CocoaPods 的人:

如果您使用的是 Firebase,那么您有一些包含 Firebase.hmodule.modulemap 文件的文件夹。例如 - YOUR_PROJECT_DIR/Linking

如果您的主项目目标工作正常,那么您应该转至 ProjectSettings -> Targets。 Select 测试目标。搜索 User headers 并将路径添加到 YOUR_PROJECT_DIR/Linking。 Select recursive 选项,你应该可以开始了。

详情请看截图:

更简单的方法也有效:

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

    target :MyAppTests
end