单元测试 iOS 应用程序扩展

Posted

技术标签:

【中文标题】单元测试 iOS 应用程序扩展【英文标题】:Unit testing iOS app extension 【发布时间】:2016-11-14 10:08:52 【问题描述】:

我的 ios 应用有多个扩展:

今日延期

siri 扩展

信息扩展

我还创建了框架来共享通用代码。我的问题是我想要一个单元测试目标来测试所有扩展。我的 Podfile 看起来像这样:

 target 'MyApp' do
   pod 'MyFramework', :path => './MyFramework'
     target 'MyAppTests' do
       inherit! :search_paths
     end
 end

abstract_target 'Extensions' do
  pod 'MyFramework', :path => './MyFramework'
  target 'TodayExtension'
  target 'SiriExtension'
  target 'iMessageExtension'
  target 'ExtensionsTests'
end

如您所见,我创建了ExtensionsTests 目标,但我不知道如何继承所有扩展的搜索路径。我也尝试使用 @testable import TodayExtension 但我收到未定义符号的链接错误,用于架构 x86_64。

有什么办法可以解决这个问题吗?

完整的错误代码:

Undefined symbols for architecture x86_64:
  "type metadata accessor for TodayExtension.LoadingView", referenced from:
      ExtensionTests.LoadingViewTests.setUp () -> () in LoadingViewTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

编辑:

我认为这个问题很普遍:如何测试任何扩展代码?我创建了单视图项目,添加了今天的扩展,但我无法扩展代码。

在苹果文档中只有以下信息:

使用 Xcode 测试框架(即, XCTest APIs),编写测试来使用扩展代码 您的包含应用程序作为主机环境。了解更多关于 测试,请参阅使用 Xcode 进行测试。

这不是很有帮助

【问题讨论】:

在 TodayExtensions 构建设置中,将 Build Active Architecture Only 设置为 NO @shallowThought 与此设置相同的错误 设置了 Build Active Architecture Only 后能否成功构建 TodayExtension? 抱歉@shallowThought 我再次检查了,在将 Build Active Architecture 设置为 NO 后我无法构建此目标。任何想法为什么? 添加了更多信息的答案。 【参考方案1】:

我遇到了同样的问题。根据this answer,不支持以这种方式进行单元测试扩展。作为一种解决方法,您可以将要测试的代码分解到框架中,并将其包含在您的扩展目标和扩展测试目标中。

【讨论】:

【参考方案2】:

Apple 文档中的引用完全正确。

要使用 Xcode 测试框架(即 XCTest API)测试应用扩展,请编写测试以使用包含应用作为宿主环境来测试扩展代码。要了解有关测试的更多信息,请参阅使用 Xcode 进行测试。

您可能陷入了一个我发现自己经常陷入的陷阱:单元测试应该测试“单元”的功能。不要测试您在“单元”中拥有的每个小辅助功能,而是测试公共功能。框架也是如此。仅为公共功能编写测试。如果您要测试更多,那么您将花费太多时间编写测试。

您可以创建一个单元测试目标并选择您的主应用程序作为“要测试的目标”然后在测试文件中只需像主机应用程序一样加载扩展程序并测试主机应用程序将使用的交互是否正在返回正确。

【讨论】:

“像主机应用一样加载扩展”到底是什么意思?【参考方案3】:

架构 x86_64 的未定义符号

错误告诉您architecture x86_64 无法找到(不存在/不存在)TodayExtension(或其中的一部分)。架构 x86_64 是您的模拟器架构。

我怀疑您构建 TodayExtension 时将目标设置为真实设备(架构 arm x),并且 TodayExtension 构建设置 Build Active Architecture Only 设置为 YES,这意味着它为您的目标设备架构(arm x ) 而不是模拟器 (x86_64)。

修复

TodayExtensions 构建设置中(及其所有依赖项,如果有的话):

Build Active Architecture Only设置为NO

Valid Architectures 设置为arm64, armv7, armv7s, i386, x86_64(如果尚未设置)

重建TodayExtension

如果您的问题仍然存在,请仔细检查人工制品切片。在终端:

file /path/to/TodayExtension.apex/TodayExtension

它应该输出:

/path/to/TodayExtension.appex/TodayExtension: Mach-O 64-bit executable x86_64

对于您的框架:

file /path/to/MyFramework.framework/MyFramework

应该输出:

path/to//MyFramework.framework/MyFramework: Mach-O universal binary with 5 architectures
path/to//MyFramework.framework/MyFramework (for architecture x86_64):   Mach-O 64-bit dynamically linked shared library x86_64
path/to//MyFramework.framework/MyFramework (for architecture i386): Mach-O dynamically linked shared library i386
path/to//MyFramework.framework/MyFramework (for architecture armv7):    Mach-O dynamically linked shared library arm
path/to//MyFramework.framework/MyFramework (for architecture armv7s):   Mach-O dynamically linked shared library arm
path/to//MyFramework.framework/MyFramework (for architecture arm64):    Mach-O 64-bit dynamically linked shared library

【讨论】:

我需要将 Build Active Architecture Only 设置为 TodayExtension 的所有依赖项以使其工作。但是当我尝试测试 ExtensionTests 目标时,我仍然会收到该错误。我认为问题与其他事情有关。 请将完整的错误linked error for undefined symbols for architecture x86_64 添加到问题中。 您的测试目标是UITest 目标吗? type metadata accessor 很可疑。

以上是关于单元测试 iOS 应用程序扩展的主要内容,如果未能解决你的问题,请参考以下文章

如何在Xamarin.iOS本机平台中扩展tableview单元格?

具有特定配置设置的单元测试 vscode 扩展

iOS 单元测试包:为啥要启动该应用程序?

对于单元测试中没有构造函数的扩展类,Angular 10 依赖注入失败

iOS 单元测试通用应用程序

我们可以在单元测试类 1 到单元测试类 2 iOS 之间添加依赖关系吗