将目标导入单元测试和将该文件包含在目标成员中有啥区别?

Posted

技术标签:

【中文标题】将目标导入单元测试和将该文件包含在目标成员中有啥区别?【英文标题】:What's the difference between importing a target into unit testing and including that file among the target Membership?将目标导入单元测试和将该文件包含在目标成员中有什么区别? 【发布时间】:2018-06-27 19:39:30 【问题描述】:

当我编写测试时,我可以做到:

@testable import TestProduct

上述与将测试文件添加到特定目标有何不同?

最终我的问题是:如果我让我的 unitTests 成为我所有文件的目标...是否相当于这样做:

@testable import TestProduct

如果不是,那有什么区别?

【问题讨论】:

【参考方案1】:

来自标题单元测试目标的访问级别下的Swift docs(已添加重点)

当您编写具有单元测试目标的应用时,您的应用中的代码需要可供该模块使用才能进行测试。默认情况下,其他模块只能访问标记为开放或公共的实体。 但是,如果您使用 @testable 属性标记产品模块的导入声明并在启用测试的情况下编译该产品模块,则单元测试目标可以访问任何内部实体。

这些文档说@testable 属性为您的单元测试目标提供了对标记为@testable 的模块的所有内部的访问。因此,您可以避免将该模块中的单个文件手动添加到单元测试目标中。

@testable 导入通常是在大型代码库上完成的 还没有进行任何测试...因为这种方法要慢得多 而不是将要测试的文件添加到测试目标中。

【讨论】:

谢谢 Aaron,我已经编辑了问题,您可以看看吗? 此上下文中的模块是否意味着target?即FaceBookQAFacebookStage? 不,这并不意味着目标。在这种情况下,Swift 中的模块是源代码的高级封装机制。目标是 Xcode 的组织/打包功能。可以推荐访问控制部分:docs.swift.org/swift-book/LanguageGuide/AccessControl.html 单元测试目标是 Xcode 的东西(因为缺乏更好的定义 atm)。 Swift module,是一种 Swift 语言级别的访问控制机制。【参考方案2】:

亲爱的。 @testable import YourAppModuleName 存在于您的测试中 - 单元测试。这将向您的测试公开任何公共和默认符号。私有符号仍然不可用。这是在构建设置中。

在测试目标中创建一个新文件并将其命名为 MyFirstSpec.swift 之类的名称。 把这个内容放进去。 或者 创建一个框架目标。如果您不是复制文件的忠实拥护者,您可以创建一个包含您要测试的源文件的框架目标。 另外,你可以参考 github 上的自动化:https://github.com/johnsundell/playground

【讨论】:

谢谢 Ash,我已经编辑了问题,您可以看看吗?【参考方案3】:

Target 是通过在 Xcode 中运行“build”创建的最终产品。它可能 可以是应用程序、框架、静态库或单元测试包。

因此,无论您添加到特定目标的哪个文件,它都会由 xcode 构建并添加到该目标的最终产品中。

所以要回答您的问题,如果您将上述文件添加到您的测试目标中,则无需导入模块 TestProduct 即可访问您的测试目标中的文件,并且它将被复制到您的测试捆绑产品目录中

当您编写以下行时,它所做的只是使您的测试目标能够访问 TestProduct 的内部文件

@testable import TestProduct

因此,如果您将该文件添加到两个目标中,它将为每个目标构建两次,并且还将被复制到各自的产品目录中,这是真正不需要的浪费。

【讨论】:

我已经编辑了问题,你可以看看吗? 我想我的回答已经涵盖了所有内容。 因此,如果您将该文件添加到两个目标,它将为每个目标构建两次,并且还将被复制到相应的产品目录,这实际上是不必要的浪费。 有趣。但是,如果我只是将每个文件都添加到我的 testTarget 中而不是 @testable import TestProduct 我会一切都好吗? 那么提到的两个(工作)场景是否 100% 相同? 您的测试目的在这两种情况下都将实现,但在重复编译和将源代码复制到测试包方面,它们采用的路径不同。所以理想情况下,您应该始终遵循第一种方法。

以上是关于将目标导入单元测试和将该文件包含在目标成员中有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

更改部署目标后无法再将应用模块导入单元测试

访问 OCUnit 测试目标中的 UIImage

Xcode 4:为啥我不能将头文件添加到单元测试目标?

我是不是需要在需要时手动将每个 *.m 文件添加到我的单元测试目标?

深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息

向 Swift 单元测试目标添加类型函数