例如,我不想运行从本地数据中选择的功能的测试,直到使用 icloud 数据填充本地数据的测试成功。
我认为正确的单元测试应该在测试本地数据选择方法之前编写一些预定义的本地数据(人们同意吗?)。 但是,对 iCloud 的调用是异步的,因此可能会在其他测试中途返回,因此仍然需要延迟直到它们完成。
单元测试应该是原子的和独立的,所以通常不推荐这种方法。 XCTest 默认也不支持此功能。在这篇 Stackoverflow post 中有一个关于在 Objective-C 中重写
+testInvocations
以按照您想要的顺序返回 NSInvocation
对象的讨论。
这里有几个选项需要考虑。一种是在
setUp
中执行初始测试配置。在所有测试用例运行之前执行一次的全局设置可以进入类级别 setUp
方法。如果您想在每个测试运行之前执行设置,那么您可以创建一个实例级别 setUp
方法。 (还有匹配的 tearDown
方法在测试运行后执行)。 XCTest 文档有更多详细信息此处。请注意,您需要使用此Stackoverflow帖子中描述的信号量模式来确保所有异步调用在运行测试之前完成。
我认为处理此问题的最直接方法是使用
expectationWithDescription
类将 iCloud 调用包含在同一单元测试中。简而言之,您将执行以下四个步骤:
fulfill()
期望。这将表明期望已得到满足。waitForExpectationsWithTimeout()
方法。您将在超时期限内调用此方法;如果在此期间没有达到预期,则可能会导致测试失败、日志输出等失败。Stackoverflow 帖子中还提供了涵盖异步调用的期望代码示例。
在
XCTestExpectation
内部使用setUpWithError
对我有用。
override func setUpWithError() throws {
let expectation = self.expectation(description: "configureSDK")
SDKInstance.configureSDK() { status in
print("status =\(status)")
if status == .isReady {
expectation.fulfill()
}
}
wait(for: [expectation], timeout: 5)
}
func testSDKMethod() {
// your test case logic
}
如果您编写单元测试,则可以使用 Swift 测试。每个 @Suite 都可以配置为并行或串行方式运行测试。
例如:
@Suite("Run tests one after another", .serialized)
struct YourTests {
@Test
func firstTestInQueue() async throws {}
@Test
func secondTestInQueue() async throws {}
}
在此配置中,测试将依次运行,但不是并行运行。通过指定 .serialized,您可以确保维持执行顺序,避免随机执行测试。