【问题标题】:Why does instantiating a UIFont in an iphone unit test cause a crash?为什么在 iphone 单元测试中实例化 UIFont 会导致崩溃?
【发布时间】:2009-11-06 18:58:32
【问题描述】:

我正在尝试对一些实例化字体的 iphone 代码进行单元测试。我已将其范围缩小到以下崩溃单元测试:

#import "test.h"
#import <UIKit/UIKit.h>


@implementation test

- (void)testFonts {
  [UIFont systemFontOfSize:12];
}

@end

这会因错误而崩溃:

Test Case '-[test testFonts]' started.
/Developer/Tools/RunPlatformUnitTests.include: line 415: 79768 Trace/BPT trap          "${THIN_TEST_RIG}" "${OTHER_TEST_FLAGS}" "${TEST_BUNDLE_PATH}"
/Developer/Tools/RunPlatformUnitTests.include:451: error: Test rig '/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.sdk/Developer/usr/bin/otest' exited abnormally with code 133 (it may have crashed).

似乎在我的单元测试目标中我没有做一些设置来完成这项工作。你如何对实例化字体的东西进行单元测试?

【问题讨论】:

  • 您应该提供控制台输出以便更好地调试。但是,访问字体不需要额外的步骤,你这样做的方式就很好。问题是:不包括/链接到正确版本的 UIKit 或代码中的其他地方。
  • 也遇到了这个崩溃。任何调用 systemFontOfSize: 的尝试都会完全破坏它。 /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/Developer/usr/bin/otest' 异常退出,代码为 133(可能已崩溃)。
  • 嘿,我能做些什么来使下面的答案更完整/有用吗?如果没有……我可以接受汉堡吗?
  • UIFont 是 UIKit 的一部分,不能在单元测试中进行测试。您可以尝试模拟对 UIFont 的调用。
  • 这个问题可能无关紧要。查看stackoverflow.com/q/41404613/62 了解更多信息。

标签: iphone unit-testing xcode


【解决方案1】:

我的一个朋友最近遇到了这个问题,我挖出了我成功设置的最后一个项目。诀窍是在应用程序测试中运行任何涉及 UIFont 的测试,而不是单元测试。在设置应用程序测试目标时,需要确保以下几点:

  1. 构建阶段:通过以下方式将您的生产代码带入您的测试目标 包括您的主要目标作为您的测试目标之一 依赖项,而不是在测试中包含 .m 文件 目标。这只是为了组织。
  2. BUILD SETTINGS:确保设置了测试目标的“Bundle Loader” 到$(BUILT_PRODUCTS_DIR)/Your Product Name.app/Your Product Name Again。请注意,它是.../Product.app/Product - 也就是说,那里 在路径的最后一段中没有 .app。如果你好奇 查看您所指的文件,找到您的构建产品,对 单击,选择查看包内容,然后找到可执行文件。
  3. BUILD SETTINGS:您的测试目标的“测试主机”应设置为 $(BUNDLE_LOADER)。轻轻松松。
  4. BUILD SETTINGS:测试目标的其他链接器标志应包括 -framework SenTestingKit
  5. 构建设置:“构建后测试”应为否。
  6. SCHEME:“构建”应包括您的测试目标和您的主要目标 目标,在两个目标中选择“测试”唯一的框。
  7. 方案:“测试”应仅包含您的测试目标。它的文件 包含将自动添加到列表中。

...希望这足以让你们继续前进。并非所有内容都清楚地记录在一个地方,并且弄清楚如何让这两种测试运行所花费的时间和痛苦比我想承认的要多。

奇怪的是,Apple 似乎已经在这件事上撤下了自己的 doco。我想知道是否会有另一个变化......

如果您对上述内容有任何补充,请联系我。这不是设置应用程序测试的完整指南,但以上是我遇到的未记录的绊脚石。 FMI,我强烈推荐this CocoaWithLove article

【讨论】:

  • 对于您列表中的第二步:是否可以通过某种变量以某种方式概括“您的产品名称”?我问的原因是我们有一个单独的 iphone 和 ipod 应用程序,它们共享相同的代码,但不共享特定于设备的资源(图像和 xib 等)。每当我运行单元测试时,我都必须选择一个方案并使用它,因为单元测试包只能以这种方式引用一个应用程序。我想让它通用,以便我可以在测试时选择其中一个。 ${PRODUCT_NAME} 不起作用,因为它指的是单元测试包本身,而不是应用包。
  • 嗯...好问题。让我确保我了解您的目标...您想要一个可用于测试这两个应用程序的目标?我不知道这是否会成功。您将如何指示您希望测试目标测试哪个应用程序?让我感到困惑的是“我想把它变成通用的,这样我可以在测试时选择其中一个”这句话让我感到困惑。一个是什么? (在下一条评论中继续)
  • 现在...如果您想拥有两个独立的测试方案,每个测试方案都将测试不同的应用程序,这并不难。我不知道如何为产品名称使用变量,但是对于两个目标,您可以在各自的构建设置中使用不同的常量值。这就是我要和这个一起去的方式。如果我完全误解了你(总是可能的 ;)),请解释一下你的目的,我会尽力提供帮助。
  • 通用我的意思是不对应用程序目标名称进行硬编码,以便我可以让一个单元测试包能够测试我的 iPhone 目标和 iPad 目标。如果在测试之前选择了 ipad 目标,我不想选择 iPhone 应用程序方案:)。我意识到我可以克隆我现有的单元测试包并更改设置,但必须同时维护两者是我宁愿避免的事情,特别是因为我们还有(出于复杂的原因)我们的 iphone 和 ipad 目标的另一个副本,其中包含不同的代码,这意味着我必须维护 4 个单元测试包而不是一两个。
  • 只是一个简短的说明,我有一个我正在处理的库,我遇到了同样的问题。我没有需要它的步骤的应用程序。但事实证明,您可以只创建一个空的应用程序目标并将其用于此目的。谢谢@beOn。
【解决方案2】:

它并没有很好地说明它,但 Apple 的测试工具包将单元测试分为两个单独的类别:

  • 逻辑测试

    这些测试检查正确 您的代码的功能 洁净室环境。

  • 应用测试

    这些测试检查功能 运行中的代码 应用。

似乎有很多与 UI 相关的代码无法在“逻辑测试”案例中运行。有关逻辑测试与应用程序测试的更多信息,请点击此处。

http://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/UnitTesting/01-Unit-Test_Overview/overview.html

【讨论】:

  • 您提供的链接已不存在。你是对的。 UIFont 是 UIKit 的一部分,不能在单元测试中测试
【解决方案3】:

我在 3.2(和 3.1.3)中看到了这个确切的问题。我在两台不同的机器上看到过,所以我不认为我的 SDK 坏了。

我创建了一个新的基于 iPhone 视图的项目,并添加了一个单元测试和一个测试用例。

这是作为逻辑测试设置的。

控制台输出如下:

Test Case '-[TestTests testTests]' started.
/Developer/Tools/RunPlatformUnitTests.include: line 415: 21141 Trace/BPT trap               "${THIN_TEST_RIG}" "${OTHER_TEST_FLAGS}" "${TEST_BUNDLE_PATH}"
/Developer/Tools/RunPlatformUnitTests.include:451: error: Test rig  '/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.3.sdk/Deve loper/usr/bin/otest' exited abnormally with code 133 (it may have crashed).
Command /bin/sh failed with exit code 1

如果我为调试设置了单元测试,那么我可以看到崩溃,并带有以下堆栈跟踪:

#0  0x00342d51 in __HALT 
#1  0x002947c7 in _CFRuntimeCreateInstance
#2  0x00b8441e in GSFontCreateWithName
#3  0x028c8f31 in +[UIFont systemFontOfSize:]

我可以理解 Kendall 的观点(UIKit 的东西可能只在设备上工作),但这似乎在任何地方都没有很好地记录。

【讨论】:

    【解决方案4】:

    你在设备上试过了吗?我似乎记得你只能在设备上运行时在测试中包含 UIKit 的东西,而不是针对模拟器......

    【讨论】:

    【解决方案5】:

    抱歉,我在 Xcode 5 上进行 XCT 测试时遇到了一些问题,它与这个线程有关

    引用:

    "如果没有 UIApplication,许多 UIKit 类将无法工作 尝试添加代码以通过该项目中的测试表明,其他测试也必须有条件地从 LogicTests 中排除:

    默认的 loadView 方法会失败——所以 testLoadView 方法被 #ifdef 淘汰了。

    任何分配/初始化 UILabel 的尝试都会失败。我不知道为什么,但正因为如此,标签上的所有测试都必须是#ifdef'd。

    一般来说,不要指望 UIKit 框架的任何东西在你的逻辑测试中起作用。其他框架几乎总是可以工作(在这个应用程序中,CoreLocation 和 Foundation 框架可以正常工作)。

    在 UIKit 中,一些元素会起作用——例如,UIWebView 在我的测试中没有任何问题。在您尝试之前,在 LogicTests 包中哪些用户界面对象将失败(没有实际运行的应用程序)永远不会真正清楚,但这些失败是您仍然需要运行应用程序测试来验证的原因 - 应用程序测试更具权威性UIKit 中任何内容的结果。”

    网址:http://www.cocoawithlove.com/2009/12/sample-iphone-application-with-complete.html

    【讨论】:

      【解决方案6】:

      在项目/目标列表的“目标”部分中选择您的单元测试目标,然后在“常规”部分下选择您的主机应用作为主应用,其中包含字体。

      这解决了我的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-23
        • 2021-06-28
        • 1970-01-01
        • 2015-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多