Ios Xcode单元测试生成失败,错误为“;架构x86“U 64”的未定义符号;

Ios Xcode单元测试生成失败,错误为“;架构x86“U 64”的未定义符号;,ios,xcode,Ios,Xcode,我的unittest目标生成失败,错误如下: Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_MCStore", referenced from: objc-class-ref in MCStoreTests.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1

我的unittest目标生成失败,错误如下:

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

  • Xcode6.2
  • iOS8.2 SDK
我检查的内容:

  • 默认情况下隐藏的符号
    为否
  • 其他链接器标志
    是-框架测试
  • 框架搜索路径
    为$(SDKROOT)/Developer/Library/Frameworks$(继承)
根据这一点,我需要在unittest target
构建设置中使用以下内容设置
捆绑加载程序


$(build\u PRODUCTS\u DIR)/MyExistingApp.app/MyExistingApp

遇到了同样的问题。
对我来说,解决这个问题的方法是在测试目标
构建设置
中将
启用模块(c和objective-c)
设置为,至少从Xcode 7.3开始,测试目标允许您选择“主机应用程序”。在测试目标(但目前不是UI测试目标)中,这会自动填充“测试主机”构建设置,但不会填充“捆绑加载程序”,这可能导致找不到类

考虑到这一点,如果您将测试目标的“Bundle Loader”构建设置设置为
$(test\u HOST)
,则即使您更改了主机应用程序,它也将始终包含正确的值


这实际上与@yuwen yan发布的链接中给出的建议相反,应该会减少工作量。

以下是我在尝试在Xcode 9中添加单元测试目标时为解决此问题而执行的步骤:

  • 转到“管理方案”
  • 单击底部的“+”按钮
  • 选择新添加的目标并选择“确定”
  • 确保为新添加的目标选择了“共享”选项

  • 将测试目标添加到2或3个Xcode版本之前创建的旧项目后,遇到相同的链接器错误。此外,project具有各种xcodeproject/target/bundle名称。所有可能的重命名、清理、
    构建设置
    构建阶段
    方案
    操作对我都不起作用


    经过长时间的努力,真正起作用的是在最新的Xcode版本中重新创建项目和所有目标。它终于链接了!在这种情况下,您甚至不需要手动修改
    搜索路径
    捆绑加载程序
    ,Xcode将为您执行此操作。

    此错误可能是由于测试目标类型错误,即ui测试目标

    UI测试目标不能使用主目标的内部结构,即使是
    @testable
    导入也不行。单元测试目标OTOH可以使用内部构件


    (我相信这在某些XCode版本中已经发生了变化,这会导致混乱。典型的方法是在ui测试目标中包含来自原始目标的大量文件。一种正确的方法是设计ui测试,使其不需要或不使用来自主目标的太多代码。)

    因此以下是对我有效的方法

    override func setUp() {
    
        super.setUp()
    
        let promise = expectation(description: "App has finished running")
    
        DispatchQueue.global(qos: .background).async{
            // Wait on the background thread
            sleep(4)
            DispatchQueue.main.async {
                // Fullfill the promise in the main thread
                promise.fulfill()
            }
        }
    
        // Initialize the storyboard
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
    
        // Get the view controller
        sut = storyboard.instantiateViewController(withIdentifier: String(describing: ViewController.self)) as? ViewController
        _ = sut.view
    
        waitForExpectations(timeout: 5) { (_) in
            // Finish set up after the app is done running its code
        }
    
    }// End setUp() Method
    

    对我有效的方法就是在pod文件上使用测试目标

    target 'MyAppName' do
      use_frameworks!
    
      pod 'SwiftLint'
      pod 'RxSwift'
      pod 'RxCocoa'
      pod 'RxDataSources'
      pod 'RxGRDB'
    
      target 'UnitTestTarget' do
        inherit! :search_paths  
      end
    end
    

    在我的特殊情况下,我试图测试
    release
    configuration,结果得到了这个特殊的错误。在对不同的编译标志进行了实验之后,我发现在我的项目上为发布配置设置
    启用可测试性
    (不是特定的目标,但可能也可以工作)就成功了


    在我的例子中,当我需要测试作为我应用程序一部分的框架中存在的类时,我遇到了这个错误:

    测试框架类。
    1.将测试目标添加到macOS。
    2.选择项目/目标窗口。选择测试目标。
    3.转到“构建阶段”、“将二进制文件与库链接”添加要测试的框架。

    4.在测试类(setup/teardown)中,将“import”添加到要从该框架测试的类中

    Xcode 12.3(12C33)–我刚刚删除了测试目标和所有引用。然后创建新的测试目标,并添加所有测试文件✓ just works

    在哪里实现了
    MCStore
    类?它在我的应用程序目标中实现。测试目标包括该实现文件?不,我已将我的应用程序目标添加到unittest目标依赖项。答案是救命的家伙!!!我很高兴我偶然发现了它!!!非常感谢!!!为什么这样做有效?为什么这不能在XCode中开箱即用呢?这些线路值黄金!!!非常感谢。帮助我解决了一个有单元测试、ui测试和不同部署目标的项目中无休止的Mach-O链接器错误。我必须使用XCode 8.2创建的全新项目来完成这项工作。另外请注意-步骤>返回到你的应用目标(而不是测试目标),将Symbols Hidden by Default build setting(默认生成设置隐藏的符号)设置为NO(否)。只有在您选择build settings(生成设置)下的“All”(所有)时,此选项才可见。我找到了
    $(TEST_HOST)
    作为默认配置,但是仍然找不到我的一个播客。在Xcode9.2中,它现在处于测试目标>生成设置>测试>测试主机下。添加$(测试主机)仍然有效。然而,我也更新了我的CoCoapod,我注意到测试目标在Xcode版本之间会有某种程度的中断。所以这类人有了新的开始。