在等待期望时使用 XCTFail 不会阻止超时

Using XCTFail when waiting on an expectation does not prevent timeout

当运行一个异步操作的XCTest时,调用XCTFail()不会立即使测试失败,这是我的期望。相反,调用 wait 后剩余的任何超时时间都会首先耗尽,这会不必要地延长测试时间,还会产生令人困惑的失败消息,暗示测试由于超时而失败,而实际上它明确地失败了。

func testFoo() {
    let x = expectation(description: "foo")

    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        XCTFail("bar")
    }

    wait(for: [x], timeout: 5)
}

在上面的例子中,虽然失败发生在大约 2 秒后,但直到 5 秒的超时时间过去后测试才完成。当我第一次注意到这种行为时,我以为我做错了什么,但这似乎就是它的工作方式,至少对于当前版本的 Xcode (9.2).

由于我没有通过 google 或 Whosebug 搜索找到任何提及此问题的信息,因此我将分享我找到的解决方法。

我发现调用XCTFail()后XCTestExpectation仍然可以实现,不算pass,直接过期wait。因此,将其应用于我的初始示例:

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
    XCTFail("bar")
    x.fulfill()
}

这可能是 Apple 所期望的,但它对我来说并不直观,而且我在任何地方都找不到它的文档。所以希望这可以节省其他人我花在困惑上的时间。