xcode 为什么我不想启用可测试性

laximzn5  于 2023-03-04  发布在  其他
关注(0)|答案(2)|浏览(145)

在ios应用程序中,默认行为似乎是测试编译失败。

为什么我希望它是默认的呢?当然,在最坏的情况下,我希望Debug启用它?启用可测试性实际上做了什么改变?

sauutmhj

sauutmhj1#

我在追踪另一个问题时偶然发现了这个问题。但是也许我可以提供一个场景。为什么你不想启用可测试性呢?

  • f可见性=隐藏。
    如果你想使用GCC_SYMBOLS_PRIVATE_EXTERN(aka Symbols Hidden By Default),启用可测试性有更高的优先级,并且会覆盖它。
    在我的例子中,我有一个从Debug复制的配置,因此启用可测试性== YES。我有一个外部静态库,它是用-fvisibility=hidden构建的,用于构建我自己的静态库之一(用Xcode构建)。然而,当构建我的调试构建时,我得到了错误,例如(我编辑了函数名和路径)
    显示所有消息:函数中的直接访问...意味着弱符号在运行时不能被重写。这可能是由于使用不同的可见性设置编译不同的翻译单元造成的。
    从苹果的文档这里:
    https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/04-writing_tests.html
    当您将Enable Testability build设置设为Yes时(对于新项目中的测试构建默认为true),Xcode会在编译过程中包含-enable-testing标志,这使得在编译模块中声明的Swift实体有资格获得更高级别的访问权限。
    看起来它也是Swift的可访问性,所以如果你不使用Xcode的测试和Swift,看起来你也可以不使用它。
zvokhttg

zvokhttg2#

tl; dr答案

可测试性为单元测试提供了对通常无法从模块/框架外部访问的符号的访问,因此可以为这些组件编写测试。

完整答案

下面是Testability在不同上下文中的含义的概述(可能不完整)。

斯威夫特

对于Swift,可测试性意味着符号的访问修饰符可以在导入过程中被覆盖。
通常Swift知道以下访问修饰符:

  • open:类在当前模块外部可见,可以从当前模块外部重写(除非final)。open只能应用于类。
  • public:符号在当前模块外部可见。如果符号是类,则它可见,但不能从当前模块外部重写。
  • internal:符号仅在当前模块中可见。顶级符号的默认访问修饰符。
  • fileprivate:符号仅在当前文件中可见。
  • private:符号仅在当前封闭范围内可见。如果应用于顶级符号,则行为与fileprivate完全相同,因为文件本身是封闭范围。

启用Testability本身不会改变任何东西,但它允许您导入一个模块进行测试。

import Module

你能做的

@testable import Module

这会产生以下效果:
所有publicinternal的类都被视为open。所有其他internal的符号都被视为publicfileprivateprivate的符号保留其访问修饰符。

目标语言-C

对于ObjC,可测试性直接改变符号的可见性。
默认情况下,ObjC代码中的所有符号在Swift中都被视为public,但类除外,它们在Swift中被视为open
您可以将符号声明为__private_extern__,在这种情况下,它们的行为类似于Swift中的internal;您也可以将某些符号声明为static(而不是类或协议),在这种情况下,它们的行为类似于Swift中的fileprivate
在Xcode构建设置中,您可以启用Symbols Hidden by Default,它会自动声明所有符号为__private_extern__,除非它们是static。在当前模块之外可见的符号必须使用__attribute__((visibility("default")))标记为公共符号,例如,您可以使用define:

#define public __attribute__((visibility("default")))

public
@interface MyClass : NSObject

当您启用可测试性时,默认的可见性被重新设置为public,从而覆盖Xcode构建设置Symbols Hidden by Default。同时,定义__private_extern__也被更改,也意味着公共可见性。只有static符号保持隐藏。

    • 注意:**如果手动添加编译器标记-fvisibility=hidden,默认情况下会强制隐藏所有符号,就像构建设置Symbols Hidden by Default一样,但是这不能被可测试性覆盖。另外,如果使用__attribute__((visibility("hidden")))显式标记隐藏符号,这也不能被覆盖。

框架

对于框架,可测试性改变了project头的可见性。
默认情况下,框架头文件有三个可见性级别:

  • project:头文件仅在构建框架本身时可用。
  • private:头在构建框架以及链接到该框架时可用,但在将该框架嵌入到应用程序之前会被删除。
  • public:标头始终位于框架内,即使框架嵌入到应用程序中。

喜欢框架时,project标头中的声明不可用。启用可测试性时,project标头被视为private标头,因此链接到框架的单元测试能够访问仅在project标头中声明的符号,并且通常对导入该框架的代码不可见。

相关问题