xcode - 如何在 Xcode 4.5 "Command Line Tool"项目中设置工作逻辑单元测试目标?

标签 xcode unit-testing linker-errors xcode4.5 command-line-tool

在为特定场景设置单元测试时遇到问题。这是我正在尝试的:

  • 在 Xcode 4.5 中,我创建了一个简单的 OSX “命令行工具” 应用程序项目(基础)。
    请注意,Xcode提供自动将单元测试添加到“命令行工具”项目的选项 - 所以请不要建议勾选复选框;它不在那里:-/

  • 在我的项目中,我创建了一个简单的示例类,我想测试它;例如“形状”。

  • 我按照 Apple 的 Xcode 单元测试指南 中的说明进行操作 Setting Up Unit-Testing in a Project :

    • 我向我的项目添加了一个单元测试目标,并且

    • 我编辑了“测试”方案以在新目标中运行测试。

  • 在测试项目的实现 (.m) 文件中,我添加了 Shape.h 的导入以及 setUp() 方法中的代码来实例化形状并将其分配给实例变量。

那时,我决定看看事情是否会构建以及默认测试是否仍然会运行。但是,当我从菜单中选择产品...测试时,构建失败并出现以下错误:

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

解释此错误不是问题。我发现单元测试目标没有链接到包含 Shape 实现的二进制文件。但是,我(还)还没有理解 Xcode 单元测试和目标配置。所以:

为了让测试目标链接到命令行工具的结果输出,我需要做什么?我可以从单元测试目标链接到命令行可执行文件吗? Apple 的文档看起来特定于常规 OSX 应用程序 (*.app) 和 iOS 应用程序,而这两者都不是。

我有业务逻辑类,我想在命令行工具设置中开发(首先),所以我想了解我需要做什么才能让单元测试目标在“命令行工具”类型的项目。 谢谢!

(注:请注意,我有兴趣命令行运行我的单元测试 - Stack Overflow 已经就如何做到这一点提出了“类似”问题 -而是在“命令行工具”类型项目上运行单元测试,并且仍然在 Xcode 内进行。)

最佳答案

我已经确定了一种我认为合适的解决方法,除了添加目标之外,该解决方法似乎没有明显的缺点。

简而言之:该解决方案涉及添加静态库目标,以利用 Xcode 围绕此类目标创建和运行单元测试代码的能力。然后,命令行工具目标委托(delegate)给静态库,其中定义了一个类似于 main() 的备用函数,并由真正的 main() 入口点调用。命令行工具不含重要代码,因此单元测试目标可以访问所有值得测试的内容。

步骤如下:

  • 在空的 Xcode 中,从菜单中选择文件...新建项目

  • 在出现的对话框中,选择OS X...应用程序...命令行工具。出于本示例的目的,我假设它名为 SampleCmd

创建基本命令行工具项目后:

  • 从菜单中选择文件...新建...目标

  • 在出现的对话框中,选择OS X...Framework & Library...Cocoa Library。出于本示例的目的,我假设它名为 SampleCmdLogic

  • 选择静态类型,这样命令行工具将仍然是独立的可执行文件。

  • 确保选中包括单元测试复选框。

静态库项目创建后:

  • main() 函数从 main.m 复制到 SampleCmdLogic.m,替换 @implementation block 。 (此文件仅保存主入口点。可以为 Objective-C 类等添加其他文件) 将函数重命名libMain()

  • SampleCmdLogic.h 中,添加新 libMain() 的声明,替换 @interface block :
    int libMain(int argc, const char * argv[]);

  • 在命令行工具的 main.m 中,在顶部添加 #import "SampleCmdLogic.h"

  • 在命令行工具的main.m中,将真正的main()函数的全部内容更改为:
    返回 libMain(argc, argv);

代码现已准备就绪,但需要进行链接步骤:

  • SampleCmd 的项目设置中,在构建阶段下,展开目标依赖项并添加 (+) SampleCmdLogic 作为依赖项.

  • SampleCmd 的项目设置中,在构建阶段下,展开将二进制文件与库链接并添加 (+) libSampleCmdLogic.a

现在一切都准备好了。当您更改为 SampleCmd 目标并从菜单中选择Product..Run时,构建应该成功并按预期生成输出。当您更改为 SampleCmdLogic 目标并从菜单中选择Product...Test时,构建应该成功并且单元测试将运行。报告的单一问题是 Xcode 在 SampleCmdLogicTests.m 中插入的初始默认失败单元测试断言。这是预期的结果。

从现在开始,继续将所有逻辑和相应的测试添加到 SampleCmdLogic 目标中。 SampleCmd 目标保持简单,仅提供命令行工具入口点。

关于xcode - 如何在 Xcode 4.5 "Command Line Tool"项目中设置工作逻辑单元测试目标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13198130/

相关文章:

ios - Xcode 不从 CUICatalog 加载图像

ios - 如何在 Swift 4 中使用启动屏幕或图像来阻止 secret 信息?

ios - 将 "Inter-App Audio"权利添加到您的权利文件中

c# - 实例化其他类的单元测试类

java - Mockito 对象为 null

unit-testing - 为什么单元测试不能连接到 websocket

c++ - std::string::empty 的 undefined symbol 错误; Mac OS High Sierra 上的 c++ 标准方法链接错误

c++ - 我可以使用 declval 来构造一个未使用的返回值吗?

c++ - 处理多个功能文件时 Cucumber-cpp 上的链接器错误

iphone - 以编程方式触发 didEndOnExit