如何使用 NSDebugEnabled、NSZombieEnabled、MallocStackLogging 运行 OCUnit (SenTestingKit)?

发布于 2024-09-24 14:07:59 字数 372 浏览 5 评论 0原文

我遇到了类似于这篇文章中的错误。现在,我确信我在某个地方犯了一些愚蠢的错误,可能与释放对象或观察者或其他什么有关,但由于我似乎找不到调试代码的方法,我想我可以使用NSDebugEnabled、NSZombieEnabled 和 MallocStackLogging(如此处所示)。

使用OCUnit可以完成吗?如果是这样,怎么办?我只是找不到“可执行文件”来设置这些参数...

谢谢! 阿维亚德。

I have an error similar to the one in this post. Now, I'm sure I've made some stupid error somewhere, probably related to releasing an object or an observer or what-not, but since I can't seem to find a way to debug the code I thought I could use the NSDebugEnabled, NSZombieEnabled and MallocStackLogging (as shown here).

Can it be done using OCUnit? If so, how? I just can't find an "executable" to set these parameters on...

Thanks!
Aviad.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

懷念過去 2024-10-01 14:07:59

不幸的是,戴夫的解决方案不起作用——我不断地犯错。我最终让 GHUnit 在我的项目上工作,通过调试发现了问题,但它有自己的问题,所以我现在同时使用它和 OCUnit,后者在显示结果方面稍微更好地集成结果选项卡。

叹息。我们什么时候才能看到一个好的、完整的 Obj-C 单元测试框架?

Unfortunately, Dave's solution didn't work - I kept getting errors and mistakes. I eventually got GHUnit to work on my project, found the problem by debugging, but it had its own problems so I now use both it and OCUnit which is slightly better integrated in terms of showing the results in the results tab.

sigh. When will we get to see a good, complete unit testing framework for Obj-C?

我不吻晚风 2024-10-01 14:07:59

这可能已在最近的 Xcode 中得到修复,但我通过执行“

  1. 进入方案(cmd <)
  2. 打开测试”,然后“参数”选项卡
  3. 取消选中“使用运行操作的参数和环境变量”
  4. “+”环境变量“NSZombieEnabled”= “是的”

This may have been fixed in recent Xcodes, but I get zombies by doing

  1. Go into schemes (cmd <)
  2. Open Test, then Arguments tab
  3. Uncheck "Use the Run action's arguments and environment variables"
  4. "+" an environment variable "NSZombieEnabled" = "YES"
灼痛 2024-10-01 14:07:59

嗯,NSZombieEnabled 和朋友是环境变量,这意味着它们必须在可执行文件上运行。单元测试包的默认设置是在构建过程中运行测试,而不是在执行过程中运行。

因此,解决此问题的方法是让您的测试不在构建阶段运行,而是将它们作为可执行文件的一部分运行。

我是这样做的:

  1. 在单元测试包目标内,删除“运行脚本”构建阶段。这就是编译测试后执行测试的步骤。
  2. 从“项目”菜单中,选择“新建自定义可执行文件...”并将其命名为有意义的名称,例如“otest”
  3. 将可执行文件路径设为 otest 二进制文件,该路径应位于 / Developer/Tools/otest
  4. 在 otest 可执行文件上设置以下环境变量:
    • DYLD_FRAMEWORK_PATH =>; {UnitTest.bundle}/Contents/Frameworks
    • DYLD_LIBRARY_PATH =>; {UnitTest.bundle}/Contents/Frameworks
  5. 在 otest 可执行文件上设置以下程序参数:
    • -SenTest All(这将运行所有单元测试)
    • {UnitTest.bundle}

您现在可以选择单元测试包作为活动目标,并且otest 可执行文件作为活动可执行文件,然后构建和调试。这将允许您设置断点、设置其他环境变量(例如 NSZombieEnabled)等等。

如果您只想调试某个套件或特定单元测试,可以将 -SenTest All 参数更改为 -SenTest MyUnitTestSuite-SenTest MyUnitTestSuite/myUnitTestMethod< /代码>。

Well, NSZombieEnabled and friends are environment variables, which means they have to be run on an executable. The default setup for a unit testing bundle is for the tests to be run during the build process, and not during execution.

So the way to fix this is to make it so that your tests don't run during the build phase, but instead run them as part of an executable.

Here's how I do that:

  1. Inside your Unit Test bundle target, remove the "Run Script" build phase. It's that step that executes the tests after compiling them.
  2. From the Project menu, choose "New Custom Executable..." and name it something meaningful, like "otest"
  3. Make the executable path to be the otest binary, which should be located at /Developer/Tools/otest
  4. Set the following environment variables on the otest executable:
    • DYLD_FRAMEWORK_PATH => {UnitTest.bundle}/Contents/Frameworks
    • DYLD_LIBRARY_PATH => {UnitTest.bundle}/Contents/Frameworks
  5. Set the following program arguments on the otest executable:
    • -SenTest All (this will run all of the unit tests)
    • {UnitTest.bundle}

You can now select your unit test bundle as the active target, and the otest executable as the active executable, and then build and debug. This will let you set breakpoints, set other environment variables (like NSZombieEnabled), and so on.

If you only want to debug a certain suite or specific unit test, you can change the -SenTest All argument to -SenTest MyUnitTestSuite or -SenTest MyUnitTestSuite/myUnitTestMethod.

忘年祭陌 2024-10-01 14:07:59

我花了相当长的时间,但我终于设法让它适用于我的项目。
为了创建“逻辑”测试,我遵循 Apple 关于创建逻辑测试的指南
一旦您了解逻辑测试是在构建期间运行的,这就可以正常工作。

为了能够调试这些测试,需要创建一个将调用这些测试的自定义可执行文件。 Sean Miceli 在 Grokking Cocoa 博客上发表的文章提供了执行此操作的所有信息。然而,遵循它并没有立即取得成功,需要进行一些调整。

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

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

步骤 1 - 设置目标

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

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

第 2 步 - 设置 otest

这里最重要的一点是获取正确的 otest,即适用于您当前 iOS 的版本,而不是默认的 Mac 版本。 Sean 的教程对此进行了很好的描述。以下是一些帮助我正确设置的详细信息:

  1. Go Project->New Custom Executable。这将弹出一个窗口,提示您输入可执行文件名称和可执行文件路径。
  2. 输入您想要的任何名称。
  3. 复制粘贴 iOS otest 可执行文件的路径。就我而言,这是 /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/Developer/usr/bin/otest
  4. 按 Enter 键。这将带您进入可执行文件的配置页面。
  5. 此时唯一需要更改的是选择“路径类型:相对于当前 SDK”。不要输入路径,这是在步骤 3 中完成的。

步骤 3 - 设置 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 崩溃。

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

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

  1. 将您的活动目标设置为您的单元测试目标(在我的例子中为 LogicTestsDebug)
  2. 将您的活动可执行文件设置为您的 otest 可执行文件

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

附带说明一下,如果您在运行 otest 可执行文件时遇到问题,则可能与以下问题有关:

  1. 路径错误。最初我遇到了很多问题,因为我指的是 mac otest。我在启动时不断崩溃,终止代码为 6。
  2. 参数错误。直到我从捆绑包(.octest)名称中删除空格之前,我一直遇到 otest 崩溃,退出代码为 1。
  3. 环境变量中的路径错误。 [Sean 教程][8] 有很多后续问题,让您了解其他人的尝试。我现在的这套似乎有效,所以我建议你从这个开始。

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

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

最后一件事...

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

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

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.

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 blog provides all the information to do this. Following it however did not yield immediate success and needed some tweaking.

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:

  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

Step 1 - Setting up the target

  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 "UnitTest" 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 "UnitTestsDebug" is the duplicate target.
  3. Delete the RunScript phase of the new target

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

Step 2 - Setting up 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:

  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.

Step 3 - Setting up the otest arguments and environment variables

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...

The solution: no space in your target name!

The arguments to otest are:

  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.

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

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

Step 4 - Running your otest executable

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

  1. Set your active target to your unit test target (LogicTestsDebug in my case)
  2. Set your active executable to your otest executable

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:

  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][8] 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.

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.

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

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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文