我在测试中遇到了一些失败,我发现它们似乎是由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")
}
现在,当我运行这个测试时,任务在后台线程上执行并按预期挂起,但是它保持挂起至少4秒,直到预期超时后才完成。
到目前为止,我所读到的一切都表明,你应该能够在任务中使用期望,但到目前为止,这对我来说并不奏效。
我错过了什么,或者我将不得不写一些等待代码像一个期望代替?
注释:这个测试是我的应用中一个情况的一个极大简化的版本。所以,虽然它可能没有意义作为一个独立的测试,它是一个准确的表示我正在测试。其中还有传统完成的概念,因为实际代码触发后台任务,然后通知其他代码何时完成。
Apple已经承认wait
函数在与async/await结合使用时存在问题-根据Xcode 14.3发布说明
修正:
XCTestCase.wait(for:timeout:enforceOrder:)
和相关方法现在在并发Swift函数中标记不可用,因为它们可能导致测试死锁。相反,您可以使用新的并发安全的XCTestCase.fulfillment(of:timeout:enforceOrder:)
方法。(91453026)
所以,如果你使用的是Xcode 14.3(或更高版本),你应该使用异步版本的满足(:超时:enforceOrder)
如果您可以从测试声明中删除async
,那么wait(for:)
不能工作:
waitForExpectations(timeout: 4.0)
也可以在async
测试中await
期望:
await waitForExpectations(timeout: 4.0)
我没有解释为什么这个工作,wait(for: [exp], timeout: 4.0)
不能。