【问题标题】:How can I run OCUnit (SenTestingKit) with NSDebugEnabled, NSZombieEnabled, MallocStackLogging?如何使用 NSDebugEnabled、NSZombieEnabled、MallocStackLogging 运行 OCUnit (SenTestingKit)?
【发布时间】:2023-03-14 13:58:01
【问题描述】:

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

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

谢谢! Aviad。

【问题讨论】:

    标签: unit-testing xcode ios ocunit


    【解决方案1】:

    很遗憾,Dave 的解决方案没有奏效——我不断出错。我最终让 GHUnit 来处理我的项目,通过调试发现了问题,但它有自己的问题,所以我现在同时使用它和 OCUnit,它在显示结果方面稍微更好地集成在结果选项卡。

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

    【讨论】:

      【解决方案2】:

      这可能已在最近的 Xcode 中得到修复,但我这样做会得到僵尸

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

      【讨论】:

      • +1 这是我在 Xcode 5 中启用 xctest 僵尸所必须做的。
      【解决方案3】:

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

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

      我是这样做的:

      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

      【讨论】:

      • 这个还没试过,但听起来很有希望;这种方法有什么缺点?换句话说,如果它提供了这么多,为什么它不是 Xcode 的默认模板?
      • @Aviad 我的猜测是,这需要在您的项目中添加 2 个内容:单元测试目标和 otest 可执行文件,而 Xcode (AFAIK) 不提供在一个步骤中添加两者的方法.
      • 明确一点:当您编写 {UnitTest.bundle} 时,您希望我保持原样,或者用其他东西替换它?
      • @Aviad 抱歉,应该替换为您的单元测试包的名称。
      • @Dave:所以在你的例子中,它将是“otest”(在步骤 2 中命名?)
      【解决方案4】:

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

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

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

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

      第 1 步 - 设置目标

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

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

      第 2 步 - 设置 otest

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

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

      第 3 步 - 设置 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:是
      • DYLD_NO_FIX_PREBINDING:是

      请注意,我也尝试了 DYLD_FORCE_FLAT_NAMESPACE 但这只会导致 otest 崩溃。

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

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

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

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

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

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

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

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

      最后一件事......

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

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

      【讨论】:

      • 我在 StackOverflow 上的当前状态(超级新秀)不允许我在答案中添加图像。对此感到抱歉。在接下来的几个月里,我会努力提高声誉。
      猜你喜欢
      • 2013-11-30
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多