如何运行和调试iPhone应用程序的单元测试

16

注意:现在设置单元测试比以前更容易了。本教程对于Xcode 5及以上版本不太适用。

我花了相当长的时间,但最终成功让它在我的项目中运行。 为了创建"逻辑"测试,我遵循了 苹果关于创建逻辑测试的指南。 一旦你明白了这些逻辑测试是在构建期间运行的,这个过程就很顺利了。

要能够调试这些测试,需要创建一个自定义可执行文件来调用这些测试。 Sean Miceli在Grokking Cocoa博客上的文章 提供了所有必要的信息。但是,按照他的教程进行操作并不能立即成功,需要进行一些调整。

我将重点介绍Sean教程中提供的主要步骤,并提供一些“小白”的概述,这需要我花费一些时间来理解:

  1. 设置一个包含单元测试但不运行它们的目标
  2. 设置otest可执行文件以运行测试
  3. 设置otest环境变量,使otest能够找到您的单元测试

以下操作是在XCode 3.2.5上完成的。

XCode 4版本注意事项

在XCode 4中,可以直接调试您的单元测试。只需编写测试,将其作为一个测试添加到目标中,并在其中设置断点。就这样。更多内容即将推出。

步骤1 - 设置目标

  1. 复制位于项目目标下的单元测试目标。这也会创建一个单元测试产品的副本(.octest文件)。在下面的图中,“LogicTest”是原始目标。
  2. 将单元测试目标和单元测试产品(.octest文件)重命名为相同的名称。在下面的图中,“LogicTestsDebug”是重复的目标。
  3. 删除新目标的RunScript阶段。

名称可以随便取,但最好避免空格。

enter image description here

步骤2 - 设置otest

这里最重要的一点是获取正确的otest,即适用于当前iOS而不是默认Mac版本的otest。这在Sean的教程中有很好的描述。以下是一些更多详细信息,它们帮助我正确设置这些内容:

  1. Go 项目 -> 新建自定义可执行文件。这会弹出一个窗口,提示您输入可执行文件名称和可执行文件路径。
  2. 为名称输入任何您希望的内容。
  3. 复制粘贴到 iOS otest 可执行文件的路径中。在我的情况下,路径为 /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/Developer/usr/bin/otest
  4. 按回车。这会将您带到可执行文件的配置页面。
  5. 此时要更改的唯一事项是选择“路径类型:相对于当前 SDK”。不要键入路径,这已在步骤 3 中完成。 enter image description here

第三步-设置 otest 参数和环境变量

otest 参数很容易设置...但这证明是我最大的问题。我最初将我的逻辑测试目标命名为“LogicTests Debug”。使用此名称并将“LogicTests Debug.octest”(带引号)作为 otest 参数,我一直无法使 otest 终止,退出代码为 1,永远不会停留在我的代码中...

解决方案: 目标名称中不能有空格!

otest 的参数是:

  1. -SenTest Self(或 All 或测试名称-在终端中键入“man otest”获取列表)
  2. {LogicTestsDebug}.octest-其中 {LogicTestsDebug} 需要替换为逻辑测试包名称。

以下是用于复制/粘贴的环境变量列表:

  • DYLD_ROOT_PATH:$SDKROOT
  • DYLD_FRAMEWORK_PATH:“${BUILD_PRODUCTS_DIR}:${SDK_ROOT}:${DYLD_FRAMEWORK_PATH}”
  • IPHONE_SIMULATOR_ROOT:$SDKROOT
  • CFFIXED_USER_HOME:“$ {HOME}/Library/Application Support/iPhone Simulator/User”
  • DYLD_LIBRARY_PATH:${BUILD_PRODUCTS_DIR}:${DYLD_LIBRARY_PATH}
  • DYLD_NEW_LOCAL_SHARED_REGIONS:YES
  • DYLD_NO_FIX_PREBINDING:YES

请注意,我还尝试了 DYLD_FORCE_FLAT_NAMESPACE,但这只会使 otest 崩溃。

enter image description here

第四步-运行 otest 可执行文件

要运行 otest 可执行文件并开始调试测试,您需要:

  1. 将活动目标设置为单元测试目标(在我的情况下为 LogicTestsDebug)
  2. 将活动可执行文件设置为 otest 可执行文件

您可以构建和运行可执行文件,并使用断点调试测试。

作为旁注,如果您无法运行 otest 可执行文件,原因可能是:

  1. 路径错误。一开始我指向了mac otest,导致启动时崩溃并显示终止代码6。
  2. 参数错误。直到我从bundle(.octest)名称中删除空格后,才停止otest崩溃,并显示退出代码1。
  3. 环境变量中的路径错误。Sean教程有很多后续问题,给出了其他人尝试的一些见解。我现在拥有的设置似乎可以工作,所以建议你从这里开始。

您可能会在控制台中收到一些消息,这可能会让您认为环境变量存在问题。您可能会注意到有关CFPreferences的消息。如果您运行otest时遇到问题,请不要将重点放在此消息上,因为它不会影响测试的正常运行。

enter image description here

最后,一切都正常工作后,您将能够在测试中断点停止。

enter image description here

最后一件事......

我在许多博客上读到的XCode SenTestKit集成的主要限制是无法在构建应用程序时运行测试。实际上,这实际上非常容易管理。您只需要将逻辑测试包添加为应用程序项目的依赖项即可。这将确保构建您的逻辑测试包,即运行所有测试,然后再构建您的应用程序。

要执行此操作,您可以将逻辑测试包拖放到应用程序目标上。

enter image description here


1
我很感激你撰写了一篇如何文章,但是你能否也发布一个答案并相应地标记它呢?否则,这篇帖子将永远停留在“未回答的问题”列表的顶部。唯一的其他出路是关闭此问题,这似乎不能体现你的良好意图。 - Adrian Grigore
你能提一下这个教程适用的Xcode版本吗?看起来是3.x,对吧?你有在Xcode 4上尝试过吗?你还应该添加[ios]标签。 - Palimondo
@palimondo。已完成。感谢您的评论。Xcode版本为3.2.5。我还没有在Xcode 4上进行测试,但我会根据需要更新条目。 - MiKL
这篇帖子为什么只有六个赞? - pepsi
@pepsi 嗯,也许使用OCUnit进行单元测试并不那么流行...但还是感谢关注。 - MiKL
显示剩余3条评论
2个回答

7
这篇文章旨在提供"How-to",而不是一个真正的问题。因此,这个答案只是为了让我将"How-to"标记为"已回答"。这可能会被社区标记为不规则。我可以考虑在哪里发布未来的"How-to"文章。
不过,在这个话题上还有一点需要注意。对于那些仍然想知道编写单元测试是否值得的人,我肯定会说是的!
我目前正在编写一个使用CoreData和从Web服务(XML解析)检索数据的应用程序。完整的模型可以进行测试和调试,而无需:
1. 在模拟器或设备上运行实际应用程序。不必使用设备运行测试节省了大量时间。这是每次运行之间2分钟和5秒之间的差异。 2. 在测试模型时不需要创建视图或控制器。在第一次迭代中,完整的开发和测试可以专注于模型。一旦模型通过了集成测试,其余的开发就可以跟进。
要调试XML解析,我只需使用我完全控制的“硬编码”文件即可。
关键是在实现代码功能时编写测试。从长远来看,它确实可以节省调试整个应用程序的时间。
好了,就这样吧。

2
再次感谢您的指导。StackOverflow是发布此类文章的绝佳平台。我建议您提出一个问题(例如“如何运行和调试iPhone应用程序的单元测试?”),然后将如何操作的文章作为自己问题的答案编写。我知道您只能在48小时后将其标记为最佳答案,但这似乎是在SO上发布如何操作并遵守规则的最佳方式... 再次抱歉批评您的帖子,我知道您只是想帮忙。 - Adrian Grigore
@Adrian。这是一个很好的观点。我会在未来的操作中采用这种方式。不过,你不必道歉,因为我还在学习中。所以感谢你的评论。 - MiKL
你有关于应用程序测试的建议吗?如果使用“Test”方案在模拟器上运行,应用程序测试会失败;如果在设备上使用“Run”方案运行,则不会在断点处停止。根据http://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html,“因为应用程序测试仅在设备上运行,所以您还可以使用这些测试来执行硬件测试,例如获取设备的位置。” - Heath Borders
没事了,我在测试时可能做错了什么。我可以像你的文章所提到的那样正常调试。 - Heath Borders

0

我能够通过以下简单的步骤在调试器中运行测试用例:

  1. Product > Build For > Testing
  2. 在您想要调试的测试部分设置断点
  3. Product > Test

这是在Xcode 6.0.1上进行的,似乎比上面描述的冗长过程更方便。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接