为什么 XCTest 等待期望挂起异步后台任务?

dre*_*kka 0 async-await xctest swift xctestexpectation

我在测试中遇到了一些失败,我发现它们似乎是由 XCTest 期望等待挂起实例引起的Task。即使它们位于后台线程上。

这是一个虚构的测试,它是我的应用程序中代码的极大简化版本(请原谅打印,这只是我在尝试查看排序):

    func testTask() async throws {

        let exp = expectation(description: "")
        print("Queuing")
        Task.detached(priority: .background) {
            let duration = try await ContinuousClock().measure {
                print("  Initialing task sleep")
                try await Task.sleep(for:.seconds(1))
            }
            print("  Fulfilling after \(duration)")
            exp.fulfill()
        }

        print("Waiting")
        wait(for: [exp], timeout: 4.0)
        print("Finished")
    }
Run Code Online (Sandbox Code Playgroud)

现在,当我运行此测试时,任务在后台线程上执行并按预期挂起,但它会挂起至少 4 秒,直到预期超时后才会完成。

到目前为止我读到的所有内容都表明您应该能够将期望与任务一起使用,但到目前为止它对我来说还不起作用。

我是否遗漏了一些东西,或者我是否必须编写一些等待代码来表现得像期望一样?

注意:此测试是我的应用程序中情况的极大简化版本。因此,虽然它作为独立测试可能没有意义,但它准确地代表了我正在测试的内容。其中还有传统完成的概念,因为实际代码会触发后台任务,然后通知其他代码何时完成。

Mic*_*tek 5

根据Xcode 14.3 发行说明,wait Apple 承认与async/await 结合使用的功能存在问题。

已修复:XCTestCase.wait(for:timeout:enforceOrder:)相关方法现在在并发 Swift 函数中标记为不可用,因为它们可能导致测试死锁。相反,您可以使用新的并发安全XCTestCase.fulfillment(of:timeout:enforceOrder:)方法。(91453026)

因此,如果您使用的是 Xcode 14.3(或更高版本),您应该使用异步版本的 fulfillment(of:timeout:enforceOrder:)