Swift测试给出错误"架构x86_64的未定义符号"

Tru*_*gDQ 29 testing swift swift-package-manager

我正在swift test从命令行运行以运行测试用例.这是测试用例:

import XCTest
@testable import vnk_swift

class KeyMappingTests: XCTestCase {
    static var allTests : [(String, (KeyMappingTests) -> () throws -> Void)] {
        return [
            // ("testExample", testExample),
        ]
    }

    func testExample() {
        let keyMapping = KeyMapping()
        XCTAssertNotNil(keyMapping , "PASS")
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出消息.

图片

如果我删除使用KeyMapping,一切正常:

    func testExample() {
        // let keyMapping = KeyMapping()
        XCTAssertNotNil(true , "PASS")
    }
Run Code Online (Sandbox Code Playgroud)

图片

当我尝试使用课程时,看起来有问题.我该如何解决?

(我开始时没有使用XCode这个项目,这个项目swift package init的源代码在这里:https://github.com/trungdq88/vnk-swift)

Cri*_*tik 33

我通过以下修改成功构建并测试了您的包:

  • 将包名称重命名为VnkSwift,由于某些原因,构建工具不喜欢包名称中的破折号,当生成的包名称中包含下划线时也不起作用(因此将包重命名为vnk_swift以确保import语句和包名称匹配)不起作用)
  • 重命名测试文件夹VnkSwiftTests,以便链接器知道要链接的内容; 似乎这是链接器知道链接到包的前提条件
  • 最后,重命名main.swift为其他东西(我用过utils.swift).问题是存在main.swift指示构建工具生成可执行文件,并且链接可执行文件不能很好地工作.重命名后,不得不对if代码进行注释,因为全局运行代码只能属于main.swift.

总结:

  • 避免使用非字母数字包名称
  • 包名称和测试目录名称必须同步
  • 确保您没有main.swift文件以确保可以链接包

为什么单元测试目标链接不能与可执行文件链接?

这是因为测试包和可执行包都有全局执行代码(也就是主函数),因此链接器不知道要选择哪一个.从Xcode进行测试时,测试包会运行到应用程序的上下文中 - 它不会链接到它,就像在这里的情况一样.

Xcode在创建命令行工具时也有这个问题 - 你无法对该目标进行单元测试,如果你想对代码进行单元测试,那么你必须创建一个由工具和单元测试目标链接的库(或包括两个目标中的文件)

  • 这不是一个好的解决方案。重命名“main.swift”使包成为其他东西,但不是“可执行”。您无法在此包上运行“swift run”。虽然 @Frank 的答案并不优雅,但它似乎是目前拥有带有测试的可执行 Swift 包的最简单方法。真的很伤心。 (3认同)

Fra*_*ank 17

这似乎是因为我的模块目录中有一个main.swift.这导致生成可执行文件,而不是可以链接测试用例的库.

我通过将代码分成两个模块来解决这个问题.我有测试用例的库和只包含main.swift的应用程序:

Package.swift
Sources\FooBarLib\
Sources\FooBarLib\Something.swift
Sources\FooBarLib\MoreStuff.swift
Sources\FooBarApp\main.swift
Tests\FooBarLibTests\TestSomething.swift
Run Code Online (Sandbox Code Playgroud)

然后在我的Package.swift中确保FooBarApp依赖于FooBarLib

import PackageDescription

let package = Package(
    name: "FooBar",
    targets: [
        .target(name: "FooBarLib"),
        .target(name: "FooBarApp", dependencies: ["FooBarLib"])
    ],
)
Run Code Online (Sandbox Code Playgroud)

然后在TestSomething.swift中导入FooBarLib模块

@testable import FooBarLib
import XCTest

class TestSomething: XCTestCase {
    func testFunc() {
    }
}
Run Code Online (Sandbox Code Playgroud)


Jia*_*ing 5

在 Swift 4 中,检查您是否.testTarget依赖于FooBarLib.

    .testTarget(
        name: "FooBarLibTests",
        dependencies: ["FooBarLib"]),
Run Code Online (Sandbox Code Playgroud)