XCTest 基础知识 & Waiter

基本知识

  1. 异步接口测试,可以用 XCTestExpectation。
  2. 测试性能,可用 measureBlock 接口。

关于XCTWaiter用法

简单来说就是通过delegate的方式把处理XCTExpectation的方法解耦,可以在delegate回调中处理超时,中断等异步测试用例的异常,根据实际需求,决定是否让case 通过,或是抛出一个错误。

样例代码:

class WeiboModelTest : XCTestCase {
    var model : WeiboModel?
    let bag = DisposeBag()
    let chinaCode = "001"
    var waiter : XCTWaiter?

    override func setUpWithError() throws {
        self.model = WeiboModel()
        self.waiter =  XCTWaiter(delegate: self)
    }

    func testWaiter() {
        let expectaton1:XCTestExpectation = expectation(description: "Fail1")
        DispatchQueue.global().async {
            Thread.sleep(forTimeInterval: 1)
            expectaton1.fulfill()
        }
        expectaton1.isInverted = true
        waiter?.wait(for: [expectaton1], timeout: 2)
    }
    
    func testWaiterSuccess() {
        let expectaton1:XCTestExpectation = expectation(description: "Pass")
        DispatchQueue.global().async {
            Thread.sleep(forTimeInterval: 1)
            expectaton1.fulfill()
        }
        waiter?.wait(for: [expectaton1], timeout: 0.5)
    }
}
  • 然后在delegate回调里做自定义处理
extension WeiboModelTest {
    override func waiter(_ waiter: XCTWaiter, didFulfillInvertedExpectation expectation: XCTestExpectation) {
        if (expectation.expectationDescription == "Fail") {
            XCTFail(expectation.expectationDescription)
        }
    }
    override func waiter(_ waiter: XCTWaiter, didTimeoutWithUnfulfilledExpectations unfulfilledExpectations: [XCTestExpectation]) {
        if (unfulfilledExpectations[0].expectationDescription != "Pass") {
            XCTFail(unfulfilledExpectations[0].expectationDescription)
        }
    }
}
  • 虽然两个case里的expectation都超时了,但 testWaiter 会失败; 而testWaiterSuccess 会成功。