46

我正在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")
    }
}

这是输出消息。

图片

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

    func testExample() {
        // let keyMapping = KeyMapping()
        XCTAssertNotNil(true , "PASS")
    }

图片

看起来当我尝试使用课程时出现问题。我该如何解决?

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

4

8 回答 8

54

通过进行以下修改,我成功地构建和测试了您的包:

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

总结:

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

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

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

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

于 2017-01-01T10:36:41.417 回答
30

这似乎是由于我main.swift在您的模块目录中有一个。这会导致构建一个可执行文件,而不是一个可以链接您的测试用例的库。

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

Package.swift
Sources\FooBarLib\
Sources\FooBarLib\Something.swift
Sources\FooBarLib\MoreStuff.swift
Sources\FooBarApp\main.swift
Tests\FooBarLibTests\TestSomething.swift

然后在我Package.swift确保FooBarApp取决于FooBarLib

import PackageDescription

let package = Package(
    name: "FooBar",
    targets: [
        .target(name: "FooBarLib"),
        .target(name: "FooBarApp", dependencies: ["FooBarLib"])
    ],
)

然后在TestSomething.swift你导入FooBarLib模块:

@testable import FooBarLib
import XCTest

class TestSomething: XCTestCase {
    func testFunc() {
    }
}
于 2017-01-31T11:53:30.497 回答
4

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

    .testTarget(
        name: "FooBarLibTests",
        dependencies: ["FooBarLib"]),
于 2018-02-13T08:57:36.907 回答
1

以@Cristik 的回答为基础,实际上归结为您Sources文件夹中的内容。对我来说,我有一个文件夹,Sources它需要与in完全相同Tests,只是 inTests需要以 . 为后缀Tests。所以,如果你有Sources-> Foo-Bar,你必须有Tests-> Foo-BarTests没有例外

另一个注意事项:所有破折号都将转换为下划线,因此在测试文件的顶部,您必须添加@testable import Foo_Bar.

于 2017-01-18T03:27:22.850 回答
0

我在您拥有的目录中看到了这一点vnk-swift,但在导入语句和您拥有的损坏名称中看到了这一点vnk_swift。也许这是一个处理连字符的 Xcode/编译器错误。例如,尝试在名称中不带连字符的目录和项目上重现vnkswift

希望能帮助到你

于 2016-12-31T11:13:10.067 回答
0

在我的例子中,我通过 go to show test navigator 在 Xcode 中启用测试,右键单击并启用测试。它奏效了。

于 2017-08-31T03:59:06.377 回答
0

就我而言,在迁移框架项目以将其他框架链接为 XCFramework 而不是通用框架后,某些测试无法在链接步骤中编译。

我的解决方法是将那些失败的 objc 测试转换为 Swift,问题就解决了。

于 2021-07-30T11:18:00.283 回答
-3

如果您在创建 pod 文件后添加 TestTarget。那么下面的代码可能会在 pod 文件中丢失。

target 'DemoTests' do
  inherit! :search_paths
  # Pods for testing
end

在目标结束之前添加上面的代码,如下所示。

target 'Demo' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for DocsDemo

  target 'DemoTests' do
    inherit! :search_paths
    # Pods for testing
  end

end
于 2020-04-05T14:47:16.580 回答