【问题标题】:XCode 5 unit testing: starts my appXCode 5 单元测试:启动我的应用程序
【发布时间】:2014-07-08 01:47:33
【问题描述】:

当我在 XCode 5 中运行测试时,我的 OS X 应用程序的主窗口会在运行测试时出现在屏幕上几秒钟。为什么?即使我取消注释所有测试,它仍然会打开我的主窗口。

【问题讨论】:

  • 这里投票赞成的解决方案是关于静态更改您构建的内容以排除应用程序运行位。这可能是您想要的,但一个非常简单且非常有效的替代解决方案是启动您的单元测试没有应用程序委托。不幸的是,建议这种方法的answer on this question 目前只有一个赞成票。 Another question 在这个主题上有 higher voted answers 使用委托方法。
  • 我使用动态委托,并在my answer 中对测试运行进行了改进。

标签: objective-c xcode xcode5 xctest


【解决方案1】:

您正在运行应用程序测试,而不是逻辑测试。这意味着将启动您的应用程序实例,然后运行单元测试。这允许您执行一些需要您的应用正在运行的集成测试。

Here 是设置应用测试和逻辑测试的指南。

如果你想把它改成逻辑测试(这样它运行得更快,不需要先启动你的应用程序):

  1. 为您的单元测试目标构建设置
  2. 搜索Bundle
  3. 移除 Bundle Loader 和测试主机

【讨论】:

  • 当我这样做时,测试目标无法正确链接。测试目标是由 XCode 创建的(在测试导航器中使用 New test target 选项),除此之外我没有触及它。
  • @DanielBruce 尝试添加捆绑加载器
  • 这在 Xcode 5 中是不可能的。请参阅上面的 openradar 链接:openradar.appspot.com/15859153
  • 在 XCode 6 中也不可能。
  • 适用于 Xcode7,您只需在测试目标中的 General 选项卡中将 Host Application 设置为 None
【解决方案2】:

没错,您必须从构建设置中删除“Bundle Loader”和“Test Host”。

但是您必须将必要的实现文件添加到您的单元测试目标中。必要的文件是您要在单元测试用例中使用的文件。您需要这样做,因为在逻辑测试中 XCode 不会编译整个应用程序。所以你的一些文件会丢失。

如果您遗漏了文件,这是错误消息:

Undefined symbols for architecture i386:
  "_OBJC_CLASS_$_Module", referenced from:
      objc-class-ref in Lobic Network.o
      objc-class-ref in Logic_Unit.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

您可以通过选择实现文件并打开文件检查器来添加丢失的文件。将有一个名为“Target Membership”的部分,您还可以将文件目标成员资格设置为您的单元测试。

【讨论】:

    【解决方案3】:

    使用 XCTest,应用程序文件不要需要包含在 XCTest 目标中。 XCTest 捆绑包与使这些文件在运行时可用的应用程序相关联。

    要完成这项工作,请确保在应用程序目标中将编译器选项“默认隐藏符号”设置为 NO

    为了清楚起见,这是一个带有屏幕截图的博客文章: http://zmcartor.github.io/code/2014/02/24/slim-xctest-targets

    这种方法的优点是测试目标的构建速度要快得多。

    【讨论】:

    • 我认为 Apple 要求您在运行任何测试之前拥有一个编译应用程序有点遗憾......我宁愿让我的测试与我的应用程序具有相同的依赖关系,但独立于应用程序目标编译(即主机应用程序应该为空)。这可能吗?
    • 不幸的是,链接已经死了。
    • 你好,链接已修复
    【解决方案4】:

    在 XCode 7 中,删除 Host Application 对我不起作用。事实上,我使用以下方法来避免应用运行。

    1. 设置测试方案参数

    2. main.m

      static bool isRunningTests()
      {
          NSDictionary* environment = [[NSProcessInfo processInfo] environment];
          NSString* testEnabled = environment[@"TEST_ENABLED"];
          return [testEnabled isEqualToString:@"YES"];
      }
      
    3. 修改main()

      int main(int argc, char * argv[]) {
          @autoreleasepool {
              if (isRunningTests()) {
                  return UIApplicationMain(argc, argv, nil, nil);
              } else {
                  return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
              }
          }
      }
      

    【讨论】:

      【解决方案5】:

      如果测试是针对可以在桌面和移动设备上运行的代码,您可以在没有模拟器的情况下运行它们或将它们托管在您的应用中。

      问题是您不能使用常规目标(桌面或 iOS)的方案选择器来运行测试。

      以下内容在 Xcode6 中对我有用。

      File > New Target...
      

      从 OS X 类别中选择 Cocoa 测试包。

      注意从目标下拉列表中选择None

      单击完成。如上所述将相关文件添加到新目标。

      现在创建一个方案来运行测试。

      单击右上角的方案选择器并选择New Scheme...,单击下拉列表并向下导航到新目标。现在您可以从方案选择器中选择方案,然后使用 ⌘U 运行测试。

      【讨论】:

        【解决方案6】:

        我只是在这上面浪费了一个上午。

        项目是在 XCode 4 中创建并使用 SenTesting。

        尝试在 XCode 5/XCTTest 上迁移测试

        有同样的问题 - 应用程序在模拟器中运行并且测试从未开始 在尝试了一切之后(从应用程序更改为逻辑测试,更改为 XCTest,删除 SenTesting)

        放弃创建一个干净的 XCode 5 项目。

        添加了我所有的文件并且测试运行正常。

        Storyboard 可能仍然存在问题,因为它们是使用 XCode 4 构建的。

        很激烈,但它确实有效,所以请保留它作为最后的手段。

        【讨论】:

          【解决方案7】:

          在 XCode5 上,应用确实启动了。此答案显示了如何在运行单元测试时更改其委托以使其立即退出:https://stackoverflow.com/a/20588035/239408

          【讨论】:

          • 至少对我来说,这是一个更好的解决方案。很遗憾您在这里的答案没有被投票,而另一个问题不是我在谷歌上搜索的问题!
          猜你喜欢
          • 1970-01-01
          • 2013-10-02
          • 2020-07-26
          • 2013-09-27
          • 2013-03-20
          • 2019-06-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多