使用 DispatchQueue.main.async 测试不稳定

问题描述 投票:0回答:1

断言代码在主线程上运行时,我遇到了不稳定的情况。在本地,即使重复运行,测试也会通过,但在 CI 上,它有时会失败并出现错误:“超过 10 秒超时,未达到预期。”这是我的代码的简化版本:

// =================== Production code
final class TestClass {
  var testProtocol: TestProtocol

  init(testProtocol: TestProtocol) {
    self.testProtocol = testProtocol
  }

  func funcToTest() {
    performUIUpdate {
      anProtocol.doSomething()
    }
  }
}

func performUIUpdate(using closure: @escaping () -> Void) {
  if Thread.isMainThread {
    closure()
  } else {
    DispatchQueue.main.async(execute: closure)
  }
}

protocol TestProtocol {
  func doSomething()
}

// =================== Test
final class TestProtocolMock: TestProtocol {
  var doSomethingClosure: (() -> Void)?
  func doSomething() {
    doSomethingClosure?()
  }
}

func test_funcToTest_thenDoSomethingExecuteOnMainQueue() { // the flaky test
  let testProtocol = TestProtocolMock()
  testProtocol.doSomethingClosure = {
    // then
    XCTAssertTrue(Thread.isMainThread)
    expectation.fulfill()                      // =========>> timeout error
  }
  let sut = TestClass(testProtocol: testProtocol)

  // when
  DispatchQueue.global(qos: .background).async {
    sut.handleErrorWithCompletion(error: ErrorMock.mock, completion: { _ in })
  }

  wait(for: [expectation], timeout: 10)
}

当我增加超时时,错误发生的频率似乎会降低。我不确定这种不稳定是否来自 DispatchQueue.main.async。除了mock主队列之外,还有其他方法可以让测试更稳定吗?

ios swift unit-testing
1个回答
0
投票

DispatchQueue.global(qos: .background)
不是“通用后台队列”。这是最低的优先级。在某些情况下,它甚至可能无法运行。

(强调)

您创建的维护或清理任务的服务质量等级。

后台任务在所有任务中具有最低优先级。当您的应用程序在后台运行时,将此类分配给您用来执行工作的任务或调度队列。

你很少会说这个优先事项。你的意思是

.default

。有时
.utility
(但通常是
.default
)。对于单元测试,你永远不会这么想。

© www.soinside.com 2019 - 2024. All rights reserved.