Swift 单元测试错误:找不到架构 x86_64 的符号(Swift 包管理器)

Jus*_*sch 5 linker unit-testing clang swift swift4

我无法在使用 Swift 包管理器创建的 Swift 项目中运行单元测试(即,包管理器创建的任何单元测试......我在 Xcode 中创建的那些在 Xcode 中工作正常)。我在包管理器生成的所有项目上都遇到相同的错误。为了简单起见,我尝试了一个非常基本的测试项目,对默认设置进行了尽可能少的修改,但仍然出现错误。以下是重现的步骤:

  1. 使用swift package init --type executable(模块名称为Hello)创建一个新项目
  2. 添加Xcode项目: swift package generate-xcodeproj
  3. 在 Xcode 构建设置中,确保Enable Testability为 Yes
  4. 在 swift.main 中输入这个简单的测试代码:
import Foundation

let message = "Hello, world!"
print(message)
Run Code Online (Sandbox Code Playgroud)
  1. 在 HelloTests.swift 中:
import XCTest
@testable import Hello

class HelloTests: XCTestCase {
    func testExample() {
        XCTAssert(message == "Hello, world!")
    }

    static var allTests = [
        ("testExample", testExample),
    ]
}
Run Code Online (Sandbox Code Playgroud)
  1. Package.swift 和 XCTestManifests.swift 保持原样。
  2. 它使用swift buildand构建并运行良好swift run Hello(另外,从 Xcode 内部)。
  3. 但是,swift test在 Xcode 中运行或运行任何测试时,构建失败并显示以下错误消息:
Undefined symbols for architecture x86_64:
  "Hello.message.unsafeMutableAddressor : Swift.String", referenced from:
      implicit closure #1 : @autoclosure () throws -> Swift.Bool in HelloTests.HelloTests.testExample() -> () in HelloTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

不知何故,似乎无法链接主模块,因此无法识别符号。但是,我不知道出了什么问题或如何解决它。

从 GitHub下载了其中一个示例项目,并生成了 Xcode 项目。该项目的测试在 Xcode 和终端中完美运行。我已经仔细地将示例项目与我的进行了比较,但无法分辨出有什么不同。几乎所有设置代码(Package.swift、文件结构等)和项目设置几乎相同。我能说的唯一有意义的区别是示例项目是一个库/框架,而我的项目是一个可执行文件(但似乎链接对这两种类型的工作方式相同)。否则,我无法判断他们做对了什么,我做错了。

Jus*_*sch 21

我想通了(感谢Cristik的帮助)。可执行模块是不可测试的(至少现在是这样),所以解决方案是将所有定义移动到一个库模块中,而在可执行模块中只保留 main.swift 文件。这样,所有单元测试都与库一起作为依赖项与可执行文件一起运行。package.swift 现在看起来像这样:

let package = Package(
    name: "HighestNumberPairing",
    products: [
        .executable(name: "HighestNumberPairing", targets: ["HighestNumberPairing"]),
        .library(name: "NumberPairing", targets: ["NumberPairing"]),
    ],
    dependencies: [],
    targets: [
        .target(
            name: "HighestNumberPairing",
            dependencies: ["NumberPairing"]),
        .target(
            name: "NumberPairing",
            dependencies: []),
        .testTarget(
            name: "NumberPairingTests",
            dependencies: ["NumberPairing"]),
    ]
)
Run Code Online (Sandbox Code Playgroud)

完整的程序在 Github 上

  • 您应该将其标记为绿色!你自己的答案,完全正确:) (2认同)