简体   繁体   English

Xcode unittest 构建失败,出现错误“架构 x86_64 的未定义符号”

[英]Xcode unittest build failed with error "Undefined symbols for architecture x86_64"

My unittest target build failed with below error:我的单元测试目标构建失败,出现以下错误:

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)

Basic information:基本信息:

  • Xcode6.2 Xcode6.2
  • iOS8.2 SDK iOS8.2 SDK

What I have checked:我检查过的内容:

  • Symbols Hidden by Default is No Symbols Hidden by Default为否
  • Other Linker Flags is -framework XCTest Other Linker Flags是 -framework XCTest
  • Framework Search Paths is $(SDKROOT)/Developer/Library/Frameworks $(inherited) Framework Search Paths是 $(SDKROOT)/Developer/Library/Frameworks $(inherited)

根据此链接,我需要在 unittest 目标Build Settings使用以下内容设置Bundle Loader

$(BUILT_PRODUCTS_DIR)/MyExistingApp.app/MyExistingApp

At least as of Xcode 7.3 test targets let you select a "Host Application".至少从 Xcode 7.3 测试目标开始,您可以选择“主机应用程序”。 In the Test target (but not presently the UI Test target) this automatically populates the "Test Host" build setting, but not the "Bundle Loader", which can lead to classes not being found.在 Test 目标(但目前不是 UI Test 目标)中,这会自动填充“Test Host”构建设置,但不会填充“Bundle Loader”,这会导致找不到类。

Considering this, if you set your test targets' "Bundle Loader" Build Setting to $(TEST_HOST) , it will always contain the right value even if you change the Host Application.考虑到这一点,如果您将测试目标的“Bundle Loader”构建设置设置为$(TEST_HOST) ,即使您更改主机应用程序,它也将始终包含正确的值。

This is effectively the opposite of the advice given in the link @yuwen-yan posted, and should amount to less work.这实际上@yuwen-yan 发布的链接中给出的建议相反,应该减少工作量。

This error may be the result of having wrong test target type, namely ui test target .这个错误可能是由于测试目标类型错误,即ui test target

UI test targets can't use the internals of the main target , not even with @testable imports. UI 测试目标不能使用 main target 的内部结构,甚至不能使用@testable导入。 Unit test targets OTOH can use the internals.单元测试目标 OTOH 可以使用内部结构。

See more details in this answer.在此答案中查看更多详细信息。

(I believe this has changed in some XCode version which causes confusion. Typical way is just to include a huge bunch of files from the original target in the ui test target. A proper way is to design UI tests in such a way that they don't need or use much code from the main target.) (我相信这在某些 XCode 版本中发生了变化,这会导致混淆。典型的方法是在 ui 测试目标中包含来自原始目标的大量文件。正确的方法是设计 UI 测试,使它们不不需要或使用来自主要目标的大量代码。)

Experienced the same issue.遇到了同样的问题。 What fixed it for me was setting enable modules (c and objective-c) to YES in the Testing target Build Settings .为我修复的在 Testing target Build Settings中将enable modules (c and objective-c)YES

In my particular case I was trying to test release configuration and was getting this particular error.在我的特殊情况下,我试图测试release配置并收到此特定错误。 After experimenting with different compilation flags I found out that setting Enable Testability for release configuration on my projects (not particular targets but might work too) did the trick.在尝试了不同的编译标志后,我发现在我的项目(不是特定目标,但也可能工作)上为发布配置设置Enable Testability可以解决问题。

在此处输入图片说明

What worked for me was just using the test target on the podfile.对我有用的只是在 podfile 上使用测试目标。

target 'MyAppName' do
  use_frameworks!

  pod 'SwiftLint'
  pod 'RxSwift'
  pod 'RxCocoa'
  pod 'RxDataSources'
  pod 'RxGRDB'

  target 'UnitTestTarget' do
    inherit! :search_paths  
  end
end

In my case,I got this error when I need to test class that exist in framework that was part of my app :就我而言,当我需要测试作为我的应用程序一部分的框架中存在的类时,我收到了此错误:

testing framework class.测试框架类。
1. Add testing target to macOS . 1. 将测试目标添加到 macOS 。
2. Select project/targets window. 2. 选择项目/目标窗口。 Select the test target.选择测试目标。
3. Go to “build phases”, “link binary with libraries”, add the framework you want to test . 3. 进入“构建阶段”,“用库链接二进制文件”,添加你要测试的框架
4. In the test class (setup/teardown), add “import” to the class you want to test from that framework 4.在测试类(setup/teardown)中,添加“import”到你想从该框架测试的类

Xcode 12.3 (12C33) – I just removed the testing targets and all references. Xcode 12.3 (12C33) – 我刚刚删除了测试目标和所有引用。 Then created fresh new test targets, and, added back all my test files ✓ just works然后创建新的测试目标,并添加回我所有的测试文件 ✓正常工作

Experienced the same linker error after adding test target to old project which was created 2 or 3 Xcode versions ago.将测试目标添加到 2 或 3 个 Xcode 版本之前创建的旧项目后,遇到相同的链接器错误。 Furthermore, project has various xcodeproject/target/bundle names.此外,项目有各种 xcodeproject/target/bundle 名称。 All possible renames , cleanings , Build settings , Build phases , Scheme manipulations did not worked for me.所有可能的重命名清理Build settingsBuild phasesScheme操作对我都不起作用。

What did actually worked after a long struggle is recreating the project along with all targets from scratch in latest Xcode version .经过长时间的努力,真正起作用的是在最新的 Xcode 版本中从头开始重新创建项目以及所有目标 It finally links!终于连上了! And in this case you don't even need to manually modify Search paths , Bundle loader , Xcode will do it for you.在这种情况下,您甚至不需要手动修改Search pathsBundle loader ,Xcode 会为您完成。

For me I got a similar error message when I tried writing and running unit tests in a project that previously only had UI tests.对我来说,当我尝试在以前只有 UI 测试的项目中编写和运行单元测试时,我收到了类似的错误消息。 After many hours of troubleshooting, I realized the problem was that my current testing target was only for UI tests, not unit tests.经过几个小时的故障排除,我意识到问题是我当前的测试目标用于 UI 测试,而不是单元测试。

To fix, I just needed to add a new Unit Testing Bundle target, and then make sure that each unit test file I was trying to run had its Target Membership set to the new target I just created.为了解决这个问题,我只需要添加一个新的单元测试包目标,然后确保我尝试运行的每个单元测试文件的目标成员资格设置为我刚刚创建的新目标。

my two cents for people like me got this error using new(2019..) SPM.使用 new(2019..) SPM,我为像我这样的人提供的两分钱得到了这个错误。 I got the same error importing a package in an (old) app.我在(旧)应用程序中导入包时遇到了同样的错误。

As importing packages force Yo to choose target:由于导入包迫使 Yo 选择目标:

在此处输入图像描述

you doing have them in your test te, unless You: a) add Host application too test targrt b) flag "Allow testing Host Application APIs"你在你的测试中确实有它们,除非你:a)添加主机应用程序也测试 targrt b)标记“允许测试主机应用程序 API”

as here:就像这里:

在此处输入图像描述

now remains the question how to test an app without running App too during testing....现在仍然是在测试期间如何在运行 App 的情况下测试应用程序的问题......

So here is what worked for me...所以这对我有用......

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

Below are the steps that I performed to fix the issue while trying to add unit test target in Xcode 9:以下是我在尝试在 Xcode 9 中添加单元测试目标时为解决该问题而执行的步骤:

  1. Go to 'Manage Schemes'.转到“管理方案”。
  2. Click on '+' button at the bottom.单击底部的“+”按钮。
  3. Select the newly added Target and select 'OK'.选择新添加的目标并选择“确定”。
  4. Make sure 'Shared' option is selected for the newly added target.确保为新添加的目标选择了“共享”选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM