单元测试异步等待失败:超时了 Swift

5

我正在尝试对我的应用程序进行单元测试,但大多数测试都失败了,原因是异步等待失败:超过了30秒的超时时间,并且未满足期望:"Home Code"。

我不知道为什么会这样失败,但以下是我的代码。

class HomeTest: XCTestCase {

    override func setUp() {
    }

    override func tearDown() {
    }

    func testHome() {
        let expec = expectation(description: "Home Code")
        let presenter =  HomePresenter(view: HomeTestVC(expectation: expec), source: Repository.instance)
        presenter.start()
        wait(for: [expec], timeout: 30)
    }

    func testPerformanceExample() {
        self.measure {
        }
    }

}


class HomeTestVC: HomeContract.View {
    func showRatingForLastTrip(_ trip: Trip) {}

    func setProgress(enabled: Bool) {}

    func didFail(message: String) {}

    func didShowError(error: Error) {}

    func didShowStatusCode(code: Int?) {
        XCTAssertGreaterThan(200, code ?? 0)
        self.expec.fulfill()
    }

    var expec: XCTestExpectation
    init(expectation: XCTestExpectation) {
        self.expec = expectation
    }
} 

它弹出模拟器,但只停留在第一个屏幕上。我不知道为什么。希望能得到帮助。

3个回答

4

您没有达到预期

func testExample() {
    let expec = expectation(description: "Home Code")
    someAsyncTask() { _ in 
       expectation.fulfill()
    }
    wait(for: [expec], timeout: 30)
}

请参阅使用期望测试异步操作
注意事项:
  • 请勿像目前一样将单元测试特定代码传递到生产代码中。
  • 加载VC不是异步任务,因此不需要期望。
  • 如果Home类确实触发了某些异步任务,您可能不应该直接加载它。您应该单独测试异步部分并使用模拟/存根。

这段代码并没有在生产类中运行。我只是将异步进程中获取的值传递给了一个函数。这就是为什么我分享了完整的代码。 - King
它在HomeContract.View协议中。因此,扩展它可以让我访问其中的信息。 - King
就像这样 https://github.com/omayib/TheRegistrationPage/blob/master/TheRegistrationPageTests/TheRegistrationPageTests.swift - King
有些测试成功了,而有些测试失败了。 - King
你需要评估和修复每一个。 - Scriptable
显示剩余9条评论

2

waitForExpectations() 应该放在最后

let exp = expectation(description: "wait for exp.fulfill()")

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    XCTAssertTrue(true)
    
    exp.fulfill()
}

waitForExpectations(timeout: 2) // make sure this comes after your assertions

注意:我曾尝试使用sleep(1)来创建一秒钟的延迟,但这在Xcode测试设置中并不真正起作用。如果需要延迟,请使用调度队列asyncAfter()方法,并确保waitForExpectations()是最后被调用的。


1

你需要满足期望。就像这样:

let expectation = self.expectation(description: "Alert")

DispatchQueue.main.asyncAfter(deadline: .now() + 3.0, execute: {

    expectation.fulfill()
})

waitForExpectations(timeout: 5, handler: nil)

XCTAssert(whatever)


1
这仍然会导致相同的失败。 - King
@King,请看下面的答案(确保waitForExpectations()放在最后)。 - Trev14

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接