Xcode和Swift单元测试使用ViewInspector异步查看超时

ee7vknir  于 12个月前  发布在  Swift
关注(0)|答案(1)|浏览(98)

我正在使用Xcode 15.0.1构建一个swift包,这不是一个项目。当下面测试中的wait超时时,我遇到了一个失败,它没有在test.on(\.didAppear)行上运行闭包。仅供参考,我在我的包中的其他测试中也有这个功能。
在我的Package.swift文件中,我有以下内容。

// swift-tools-version: 5.9
    // The swift-tools-version declares the minimum version of Swift required to build this package.
    
    import PackageDescription
    
    let package = Package(
        name: "MyLibrary",
        platforms: [
            .iOS(.v16)
        ],
        products: [
            // Products define the executables and libraries a package produces, and make them visible to other packages.
            .library(name: "MyLibrary", targets: ["MyLibrary"])
        ],
        dependencies: [
            // Dependencies declare other packages that this package depends on.
            // .package(url: /* package url */, from: "1.0.0"),
            .package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.0.0"),
            .package(url: "https://github.com/realm/SwiftLint.git", from: "0.53.0"),
            .package(url: "https://github.com/nalexn/ViewInspector.git", from: "0.9.8")
        ],
        targets: [
            // Targets are the basic building blocks of a package. A target can define a module or a test suite.
            // Targets can depend on other targets in this package, and on products in packages this package depends on.
            .target(
                name: "MyLibrary",
                dependencies: [],
                resources: [
                    .process("Media.xcassets")
                ],
                plugins: [
                    .plugin(name: "SwiftLintPlugin", package: "SwiftLint")
                ]
            ),
            .testTarget(
                name: "MyLibraryTests",
                dependencies: ["MyLibrary", "ViewInspector"])
        ]
    )

字符串
下面是一段无法运行的代码。它的基本结构与我的包中的代码相同。

import SwiftUI
import ViewInspector
import XCTest
@testable import MyLibrary

final class MyTests: XCTestCase {
    
    struct TestView: View {
        @Binding var text: String
        @State var display: String = ""

        internal var didAppear: ((Self) -> Void)?

        init(text: String) {
            self._text = Binding<String>.init(wrappedValue: text)
        }

        var body: some View {
            HStack {
                Text("Hello")
                Text(display)
            }
            .onChange(of: text, perform: { value in
                self.display = value
            })
        }
    }

    func testTest() throws {
        var test = TestView(text: "")

        let exp = test.on(\.didAppear) { view in
            try view.hStack().callOnChange(newValue: "World")
            XCTAssertNotNil(try view.hStack().find(text: "World"))
        }

        ViewHosting.host(view: test)
        wait(for: [exp], timeout: 1.0) // <- Fails here with a timeout
    }
 }


我在上面的测试中使用onChange来使用与我的代码中相同的更新机制。

sg3maiej

sg3maiej1#

我找到了我的问题的答案。在var body: some View变量中缺少一行。它应该包括.onAppear { self.didAppear?(self) }。因此TestView应该是:

struct TestView: View {
        @Binding var text: String
        @State var display: String = ""

        internal var didAppear: ((Self) -> Void)?

        init(text: String) {
            self._text = Binding<String>.init(wrappedValue: text)
        }

        var body: some View {
            HStack {
                Text("Hello")
                Text(display)
            }
            .onChange(of: text, perform: { value in
                self.display = value
            })
            .onAppear { self.didAppear?(self) } // <- this was missing
        }
    }

字符串
否则exp永远不会被设置,wait函数也没有什么可等待的。

相关问题