【问题标题】:How should a Swift + Objective-C project be setup for Unit Testing如何为单元测试设置 Swift + Objective-C 项目
【发布时间】:2014-09-15 21:59:18
【问题描述】:

我发现很难找到如何在 Xcode 6b4 中配置测试目标。鉴于这种情况,有人能指出我正确的方向吗?

我有一个主要是 Swift 的项目。但是,有一些第 3 方 Objective-C 依赖项被放入应用程序的桥接头中。我想为我的 Swift 代码编写测试。理想情况下,在 Swift 中。我遇到的问题是这个......

  1. 如果我创建一个 Swift 测试用例,那么编译器会抱怨它在应用程序的桥接头中找不到 Objective-C 标头。

  2. 如果我创建了一个 Objective-C 测试用例,那么我无法导入我想要测试的 Swift 类。

我唯一能做的就是编写不涉及任何 Swift 的 Objective-C 测试用例。由于 Objective-C 依赖关系,我无法编写“纯 Swift 代码/测试”。

有没有人对此有任何建议或取得成功。或者这是 Beta 4 中的当前状态?

【问题讨论】:

  • 对于 2019 年看到此问题的任何人,以下答案已过时。请参阅下面@Mike.R 的答案,了解解决此问题的正确方法。

标签: ios objective-c swift xcode6


【解决方案1】:

我不确定你是否还在寻找这个,因为 Xcode 6 不再处于测试阶段,但你可以在目标设置中将你的 Objective-C 桥接头文件添加到你的单元测试目标中。这解决了我的问题。

【讨论】:

  • 这是否使$(PRODUCT_MODULE_NAME)-Swift.h 文件在您的Objective-C 测试中可用?不适合我...
  • @yonix 这不会使 $(PRODUCT_MODULE_NAME)-Swift.h 可用,这是相反的,即在 Swift 中使用目标 c 代码
  • @Barlow Tucker,我在 2 小时的大部分时间里都在敲我的头,这是修复谢谢!!!
  • 如果 PRODUCT_MODULE_NAME 包含任何非字母数字字符,例如句点 (.),它们会在您的产品模块名称中替换为下划线 (_),并且您不能覆盖框架的产品模块名称。
【解决方案2】:

来自 Xcode 6 Beta 4 release notes 已知问题:

测试

• 用 Objective-C 编写的单元测试目前无法导入 Swift 为 应用程序目标,因此不能用于测试代码 需要这个标题。 (16931027)

• 解决方法:Swift 的单元测试 代码应该用 Swift 编写。用 Objective-C 编写的单元测试 框架目标可以通过以下方式访问 Swift 生成的接口 使用“@import FrameworkName;”导入框架模块。

因此,您目前无法在 Objective-C 中测试 Swift 代码。

同样来自发行说明:

访问控制系统的一个限制是单元测试不能 与应用程序中的类和方法交互,除非它们 标记为公开。这是因为单元测试目标不是 应用程序模块。

Chris Lattner 在开发者论坛上的 this post 上表示,他们仍在评估情况,以了解如何协调单元测试和新实施的访问控制。

因此,我希望 Swift 本身以及同时使用 Swift 和 Objective-C 的项目中的单元测试会有很多变化。

【讨论】:

  • 是的,我已经阅读了所有这些内容。所以,问题是,如果我有要测试的 Swift 类和 Swift 测试用例,当应用程序 Swift 类需要从桥接头导入 Objective-C 时,我如何使测试目标编译...
  • @DanielThorpe - 我同意,这个答案并没有真正解决你的问题。我也想针对同样使用 ObjC 框架的 Swift 代码编写 Swift 单元测试。
  • @ColinE - 是的,我设法通过创建另一个包含那些 Objective-C 依赖项的 Objective-C 框架来避免这个问题,不幸的是使用子模块,我将它们导入到我的 Swift 框架中.
  • 也许更新这个答案,因为它可以在最新版本中完成?
  • 谁能确认这仍然是一个问题,或者它实际上已经更新了?我正在使用 xcode 6.1.1(6A2008a) 并且测试将无法编译,因为它们找不到 $(PRODUCT_MODULE_NAME)-Swift.h 文件。实际上扫描了派生数据目录并找到了文件并显式导入了该文件,但在为测试构建时仍然找不到该文件。
【解决方案3】:

我们做到了这一点,一路上我看到了所有可能的错误:从情节提要获取 VC 时的模块名称错误、特定于 coredata 实体的 MyType_MyType_ 错误等等,但这是最糟糕的。

诀窍是使用构建目标中的 -Swift.h 文件而不是测试目标,因为在测试目标中有时您必须包含 objc 文件而不是 swift 文件,如果它们链接在一起,objc 将无法识别它们,但在构建目标中,一切都在那里。

  • 首先要确保测试目标的 -Swift.h 与构建目标的名称不同。

  • 在测试 .pch 或每个单独的文件中包含来自调试目标的 -Swift。

  • 通过使用以下命令编辑用户标头搜索路径,让编译器知道该文件(在派生源中)在哪里: $(OBJROOT)/MyProjectName.build/Debug-iphonesimulator/MyProjectTarget.build/DerivedSources 如果不确定就去inFinder 并找到名称。如果名称中有空格需要在空格前加\

  • 您可以在此处找到有关项目变量的更多信息:How do I print a list of "Build Settings" in Xcode project?

  • 始终搜索用户路径应设置为是

  • 不要在测试目标中包含 swift 文件,而是使用 @testable

我希望 Apple 在下一个 xcode 中解决了这个问题。

【讨论】:

  • 我犯了一个微妙的错误,我检查了我的 swift 类的目标成员资格,即主要目标 和 测试目标。这将同一类的两个版本链接到我的测试中,导致一些相等测试惨遭失败。修复方法是修改我的测试目标的Header Search Paths,按照建议从主目标中提取自动生成的*-Swift.h 标头,并取消选中我的swift文件的测试目标成员资格。
  • 我还发现这篇文章很好地概述了各种排列:medium.com/@ahimahas12/…
【解决方案4】:

我通过将“Objective-c 生成的接口标题名称”更新为“YourApplication-Swift.h”来完成工作

默认设置是生成 TargetName-Swift.h,编译器从不生成 YourApplicaitonTest-Swift.h

【讨论】:

  • 谢谢!你是救生员。在我的一个项目中,我在构建设置中没有这个(可能是用旧 Xcode 创建的),所以我将 PRODUCT_MODULE_NAME 改为没有“测试”。
  • 为此写了一篇博文:codesheriff.blogspot.co.il/2015/05/…
【解决方案5】:

当我试图弄清楚如何从我的 Swift 测试中访问我的项目的 Swift 代码时,我遇到了这个问题。我的项目和测试最初都是在 Objective-C 中开始的,所以它们都设置了所有的桥接头。

为了从我的项目中访问 Swift 类,我必须添加:

@testable import MyProjectName

到我的 Swift 测试文件的顶部。在为测试构建它之后,Xcode 识别出我的 swift 代码。

我希望这对其他人有所帮助。

【讨论】:

    【解决方案6】:

    要让 Xcode 10 在您的 Obj-C 测试中包含 swift 类,您需要在用户搜索中添加自动生成的标题 Module-Swift.h测试目标的路径。

    转到测试目标>构建设置>标题搜索路径,并添加 $CONFIGURATION_TEMP_DIR/YourProject.build/DerivedSources

    更多参考请看iOS Tests working with Objective-C and Swift class together

    【讨论】:

    • 在尝试了我能找到的所有解决方案之后,这为我解决了问题。这是这里最新的答案。
    【解决方案7】:

    我遇到了这个问题,并尝试在测试目标的构建设置中解决它。通过更改搜索路径、导入 swift 标头、在桥接头中导入内容。然而,它竟然在我的 podfile 中。我必须在测试目标中添加link_with。像这样:

    platform :ios, '8.0'
    link_with 'YourApp', 'YourAppTests'
    pod 'ThePopularPod', '1.2.3', :inhibit_warnings => true
    

    【讨论】:

    • [!] 无效的Podfile 文件:[!] Podfile 中link_with 的规范现在不支持,请改用目标块..
    【解决方案8】:

    尝试将#import "xyz-Swift.h" 语句放入预编译的头文件中。 这样,您的所有 Obj-C 标头都有不同的导入语句,具体取决于目标:

    MyProject-Prefix.pch(应用目标):

    #import "MyProject-Swift.h"
    

    MyProjectTests-Prefix.pch(测试目标):

    #import "MyProjectTests-Swift.h" 
    

    【讨论】:

    • 有人可以给我一个提示,为什么这个解决方案不好(并且被否决)?它为我解决了这个问题。我看到现在我在不需要它的 Obj-C 头文件中不必要地导入文件,但这是一件可怕的事情吗?还是有其他原因?
    猜你喜欢
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    相关资源
    最近更新 更多