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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4989668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 20:13:58  来源:igfitidea点击:

How to run and debug unit tests for an iPhone application

iphonexcodeiosunit-testingocunit

提问by MiKL

NOTE: Unit testing is a lot easier to setup nowadays. This tutorial is not really relevant for Xcode version 5 and above.

注意:现在设置单元测试要容易得多。本教程与 Xcode 5 及更高版本并不真正相关。

It took me quite some time but I finally managed to make it work for my project. To create the "logic" tests I followed Apple guidelines on creating logic tests. This works fine once you understand that the logic tests are run during build.

我花了很长时间,但我终于设法让它为我的项目工作。为了创建“逻辑”测试,我遵循了Apple 关于创建逻辑测试的指导方针。一旦您了解在构建期间运行逻辑测试,这将正常工作。

To be able to debug those tests it is required to create a custom executable that will call those tests. The article by Sean Miceli on the Grokking Cocoa blogprovides all the information to do this. Following it however did not yield immediate success and needed some tweaking.

为了能够调试这些测试,需要创建一个自定义的可执行文件来调用这些测试。本文通过对所著的Grokking可可博客肖恩·米塞利提供的所有信息来做到这一点。然而,遵循它并没有立即取得成功,需要进行一些调整。

I will go over the main steps presented in Sean's tutorial providing some "for dummies" outline which took me some time to figure out:

我将回顾 Sean 的教程中介绍的主要步骤,提供了一些“傻瓜”大纲,我花了一些时间才弄明白:

  1. Setup a target that contains the unit tests but DOES NOT run them
  2. Setup the otest executable to run the tests
  3. Setup the otest environment variables so that otest can find your unit tests
  1. 设置一个包含单元测试但不运行它们的目标
  2. 设置 otest 可执行文件以运行测试
  3. 设置 otest 环境变量,以便 otest 可以找到您的单元测试

The following was performed with XCode 3.2.5

以下是使用XCode 3.2.5执行的

Note for XCode 4

XCode 4 的注意事项

In XCode 4 it is possible to debug your unit tests DIRECTLY. Just write your test, add it to your target as one of the tests and set a breakpoint in it. That's all. More will come.

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

Step 1 - Setting up the target

第 1 步 - 设置目标

  1. Duplicate your unit tests target located under your project Targets. This will also create a duplicate of your unit tests product (.octest file). In the figure below "LogicTest" is the original target.
  2. Rename both the unit tests target and the unit tests product (.octest file) to the same name. In the figure below "LogicTestsDebug" is the duplicate target.
  3. Delete the RunScript phase of the new target
  1. 复制位于项目目标下的单元测试目标。这还将创建单元测试产品(.octest 文件)的副本。下图中“LogicTest”为原始目标。
  2. 将单元测试目标和单元测试产品(.octest 文件)重命名为相同的名称。在下图中,“LogicTestsDebug”是复制目标。
  3. 删除新目标的 RunScript 阶段

The name of both can be anything but I would avoid spaces.

两者的名称都可以是任何名称,但我会避免使用空格。

enter image description here

在此处输入图片说明

Step 2 - Setting up otest

第 2 步 - 设置 otest

The most important point here is to get the correct otest, i.e. the one for your current iOS and not the default Mac version. This is well described in Sean's tutorial. Here are a few more details which helped me setting things right:

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

  1. Go Project->New Custom Executable. This will pop open a window prompting you to enter an Executable Name and an Executable Path.
  2. Type anything you wish for the name.
  3. Copy paste the path to your iOS otest executable. In my case this was /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/Developer/usr/bin/otest
  4. Press enter. This will bring you to the configuration page of your executable.
  5. The only thing to change at this point is to select "Path Type: Relative to current SDK". Do not type in the path, this was done at step 3. enter image description here
  1. 转到项目-> 新建自定义可执行文件。这将弹出一个窗口,提示您输入可执行文件名称和可执行文件路径。
  2. 输入任何您想要的名称。
  3. 将路径复制粘贴到您的 iOS otest 可执行文件。就我而言,这是 /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/Developer/usr/bin/otest
  4. 按回车键。这将带您进入可执行文件的配置页面。
  5. 此时唯一要更改的是选择“路径类型:相对于当前 SDK”。不要输入路径,这是在步骤 3 中完成的。 在此处输入图片说明

Step 3 - Setting up the otest arguments and environment variables

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

The otest arguments are straightforward to setup... But this proved to be my biggest problem. I initially had named my logic test target "LogicTests Debug". With this name and "LogicTests Debug.octest" (with quotes) as argument to otest I kept having otest terminating with exit code 1 and NEVER stopping into my code...

otest 参数设置起来很简单……但这被证明是我最大的问题。我最初将我的逻辑测试目标命名为“LogicTests Debug”。使用这个名称和“LogicTests Debug.octest”(带引号)作为 otest 的参数,我一直让 otest 以退出代码 1 终止并且永远不会停止我的代码......

The solution: no space in your target name!

解决方法:目标名称中没有空格!

The arguments to otest are:

otest 的论据是:

  1. -SenTest Self (or All or a test name - type man otest in terminal to get the list)
  2. {LogicTestsDebug}.octest - Where {LogicTestsDebug} needs to be replaced by your logic test bundle name.
  1. -SenTest Self(或全部或测试名称 - 在终端中输入 man otest 以获取列表)
  2. {LogicTestsDebug}.octest - 其中 {LogicTestsDebug} 需要替换为您的逻辑测试包名称。

Here is the list of environment variables for copy/pasting:

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

  • 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_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:是
  • DYLD_NO_FIX_PREBINDING:是

Note that I also tried the DYLD_FORCE_FLAT_NAMESPACE but this simply made otest crash.

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

enter image description here

在此处输入图片说明

Step 4 - Running your otest executable

第 4 步 - 运行您的 otest 可执行文件

To run your otest executable and start debugging your tests you need to:

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

  1. Set your active target to your unit test target (LogicTestsDebug in my case)
  2. Set your active executable to your otest executable
  1. 将您的活动目标设置为您的单元测试目标(在我的情况下为 LogicTestsDebug)
  2. 将您的活动可执行文件设置为您的 otest 可执行文件

You can build and run your executable and debug your tests with breakpoints.

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

As a side note if you are having problems running your otest executable it can be related to:

作为旁注,如果您在运行 otest 可执行文件时遇到问题,可能与:

  1. Faulty path. I had lots of problem initially because I was pointing to the mac otest. I kept crashing on launch with termination code 6.
  2. Faulty arguments. Until I removed the space from bundle (.octest) name I kept having otest crash with exit code 1.
  3. Wrong path in environment variables. Sean tutorial has lots of follow-up questions giving some insight on what other people tried. The set I have now seems to work so I suggest you start with this.
  1. 路径错误。最初我遇到了很多问题,因为我指向的是 mac otest。我在启动时一直崩溃,终止代码为 6。
  2. 错误的论据。在我从包 (.octest) 名称中删除空格之前,我一直遇到退出代码 1 的 otest 崩溃。
  3. 环境变量中的错误路径。Sean 教程有很多后续问题,可以让您了解其他人的尝试。我现在拥有的套装似乎有效,所以我建议你从这个开始。

You may get some message in the console which might lead you to think something is wrong with your environment variables. You may notice a message regarding CFPreferences. This message is not preventing the tests from running properly so don't focus on it f you have problems running otest.

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

enter image description here

在此处输入图片说明

Last once everything is working you will be able to stop at breakpoints in your tests.

最后,一旦一切正常,您将能够在测试中的断点处停止。

enter image description here

在此处输入图片说明

One last thing...

最后一件事...

I've read on many blogs that the main limitation of the integrated XCode SenTestKit is that tests cannot be run while building the application. Well as it turns out this is in fact quite easy to manage. You simply need to add your Logic tests bundle as a dependency to your application project. This will make sure your logic tests bundle is built, i.e. all tests are run, before your application is built.

我在很多博客上读到过,集成的 XCode SenTestKit 的主要限制是在构建应用程序时无法运行测试。事实证明,这实际上很容易管理。您只需将您的 Logic 测试包作为依赖项添加到您的应用程序项目。这将确保在构建应用程序之前构建您的逻辑测试包,即运行所有测试。

To do this you can drag and drop your logic test bundle onto your application target.

为此,您可以将逻辑测试包拖放到应用程序目标上。

enter image description here

在此处输入图片说明

采纳答案by MiKL

This post is intended as a "How-to" more than a real question. Therefore this answer is just meant to allow me to mark the "How-to" as "answered". This will probably be flagged by the community as irregular. I'm up for suggestions on where to post future "How-to" articles.

这篇文章旨在作为一个“操作方法”,而不是一个真正的问题。因此,这个答案只是为了让我将“操作方法”标记为“已回答”。这可能会被社区标记为不正常。我愿意就在何处发布未来的“操作方法”文章提出建议。

One final note though on this topic. For those who still wonder whether writing unit tests is worth it I would definitely say Yes!

关于这个主题的最后一点。对于那些仍然怀疑编写单元测试是否值得的人,我肯定会说是的!

I am currently writing an application with CoreData and retrieval of data from a web service (xml parsing). The complete model can be tested and debugged without having to:

我目前正在使用 CoreData 编写一个应用程序并从 Web 服务(xml 解析)中检索数据。可以测试和调试完整的模型,而无需:

  1. run the actual application on the simulator or device. Not having to use the device to run the tests is a huge gain of time. It's the difference between 2 minutes and 5 seconds per run.
  2. without the need to create views or controllers when testing the model. The complete development and testing can focus on the model only in the first iteration. Once the model is cleared for integration the rest of the development can follow.
  1. 在模拟器或设备上运行实际应用程序。不必使用设备来运行测试是一个巨大的时间收益。这是每次运行 2 分钟和 5 秒之间的差异。
  2. 在测试模型时无需创建视图或控制器。完整的开发和测试只能在第一次迭代中专注于模型。一旦模型被清除以进行集成,就可以进行其余的开发。

To debug the xml parsing I can simply use "hard-coded" files which I completely control.

要调试 xml 解析,我可以简单地使用我完全控制的“硬编码”文件。

The crux is of course to write the tests as you implement features in the code. It really is a time saver down the line in terms of debugging of the complete application.

关键当然是在代码中实现功能时编写测试。就整个应用程序的调试而言,这确实可以节省时间。

Voilà, I'll leave it at that.

瞧,我会就此放手。

回答by vpathak

I was able to run the test case in debugger in the following simple steps:

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

  1. Product > Build For > Testing
  2. Put a break point in part of the test you want to debug
  3. Product > Test
  1. 产品 > 构建 > 测试
  2. 在要调试的部分测试中放置一个断点
  3. 产品 > 测试

This is on Xcode 6.0.1 and seems much more convenient than the long procedure described above.

这是在 Xcode 6.0.1 上,似乎比上面描述的长过程方便得多。