为什么在iphone单元测试中实例化UIFont会导致崩溃?

时间:2009-11-06 18:58:33

标签: iphone unit-testing xcode

我正在尝试对一些实例化字体的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).

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

6 个答案:

答案 0 :(得分:19)

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

  1. 构建阶段:通过以下方式将生产代码添加到测试目标中 包括你的主要目标作为你的测试目标之一 依赖项,而不是在测试中包含.m文件 目标。这仅适用于组织。
  2. 构建设置:确保设置了测试目标的“Bundle Loader” 到$(BUILT_PRODUCTS_DIR)/Your Product Name.app/Your Product Name Again。请注意,它是.../Product.app/Product - 就是那里 在路径的最后一段中没有.app。如果你好奇的话 看到你所指的文件,找到你的构建产品吧 单击,选择查看包内容,然后找到可执行文件。
  3. 构建设置:您的测试目标的“测试主机”应设置为 $(BUNDLE_LOADER)。容易腻。
  4. 构建设置:测试目标的其他链接器标志应包括 -framework SenTestingKit
  5. 构建设置:“构建后测试”应为否。
  6. 计划:“构建”应包括您的测试目标和主要测试目标 目标,“测试”是两个目标中唯一选中的框。
  7. 计划:'测试'应仅包括您的测试目标。它的文件 包含将自动添加到列表中。
  8. ...希望这足以让你们全力以赴。在一个地方并没有完全记录下来,弄清楚如何让两种测试运行花费的时间和痛苦都比我想承认的要多。

    奇怪的是,苹果公司似乎已经就此问题撤下了自己的doco。我想知道是否会有另一个变化...

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

答案 1 :(得分:9)

它没有说得很好,但Apple的测试套件将单元测试分为两个不同的类别:

  • 逻辑测试

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

  • 应用程序测试

    这些测试检查功能 您正在运行的代码 应用

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

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

答案 2 :(得分:2)

我在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:]

我可以看到肯德尔的观点(UIKit的东西可能仅适用于设备),但似乎没有在任何地方记录得很好。

答案 3 :(得分:1)

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

答案 4 :(得分:0)

很抱歉挖掘它,但我在Xcode 5上遇到了XCT测试的一些问题,并且它与此线程有关

引用:

“如果没有UIApplication,很多UIKit类都无法运行 尝试添加代码以通过此项目中的测试表明其他测试也必须从LogicTests中有条件地排除:

默认的loadView方法将失败 - 因此testLoadView方法是#ifdef'd out。

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

通常,不要指望UIKit框架中的任何内容可以在您的Logic测试中使用。其他框架几乎总是有效(在此应用程序中,CoreLocation和Foundation框架可以正常工作)。

在UIKit中,一些元素可以工作 - 例如,UIWebView在我的测试中没有任何问题。 LogicTests捆绑包中的哪些用户界面对象将失败(没有实际运行的应用程序)在您尝试之前从未真正清楚,但这些失败是您仍然需要运行应用程序测试以进行验证的原因 - 应用程序测试更具权威性在UIKit的任何结果。“

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

答案 5 :(得分:0)

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

这解决了我的问题。