XCTAssert/XCTFail 在异步回调中是不是安全?
Posted
技术标签:
【中文标题】XCTAssert/XCTFail 在异步回调中是不是安全?【英文标题】:Are XCTAssert/XCTFail safe in async callbacks?XCTAssert/XCTFail 在异步回调中是否安全? 【发布时间】:2018-07-20 03:30:20 【问题描述】:我经常看到在理论上等待期望时在调用的回调中使用XCTAssert
和XCTFail
的示例。如果超时到期,会发生什么?
一个人为的例子(随意考虑 Swift 中的等价物,应该是一样的):
XCTestExpectation *expectation = [self expectationWithDescription:@"..."];
SomethingThatTakes2Seconds(^
XCTFail(...);
[expectation fulfill];
];
[self waitForExpectationsWithTimeout:1 handler:^(NSError *error)
...
];
在这种情况下,我们将在 1 秒后使期望失败,然后 XCTFail
将在一秒后被击中。有明确的行为吗?在我的测试中,它似乎只是被忽略了,因为过程结束了。
但是,如果我堆积测试,以后的测试是否会因包含XCTFail
的块在运行时被调用而不确定地失败(假设它也是一个允许队列运行的异步测试等) ?
似乎使用__block
变量并在外部测试方法主体中执行所有断言可能是正确的做法?
【问题讨论】:
【参考方案1】:在 Objective-C 中,XCTFail
只是一个宏,最终会扩展为:
// XCTestAsserionsImpl.h
XCT_EXPORT void _XCTFailureHandler(XCTestCase *test, BOOL expected, const char *filePath, NSUInteger lineNumber, NSString *condition, NSString * __nullable format, ...) NS_FORMAT_FUNCTION(6,7);
所以即使XCTFail
被执行,上下文(文件和行号)也会被保留用于失败报告。对于完全不同的测试用例的上下文,您不会意外失败。
另外,我怀疑当您的XCTFail
在另一个成功的测试用例场景中被执行时,它不会让 Xcode 显示该测试用例失败。虽然我对_XCTFailureHandler
内部的工作原理并不了解,但当我在测试运行时编辑测试文件时,我经常看到 Xcode 无法标记测试用例的成功和失败。简而言之,我的观察使我相信失败是基于源代码位置的,而 Xcode 仅基于此提供了所有漂亮的标记——当你摆弄文件时它可能会感到困惑。
简而言之,我相信(!)一个延迟失败,如果它在拆除后执行,不会影响其他测试用例。
不过,为了验证我的说法,我很乐意看到您进行详细的实验。 :)
【讨论】:
【参考方案2】:当
[self waitForExpectationsWithTimeout:1 handler:^(NSError *error)
...
];
达到测试运行器将暂停。测试运行器在满足预期之前不会恢复运行。在这种情况下,由于 timeout 为 1 测试将在等待 1 秒后失败。
【讨论】:
没有解决 OP 的问题:XCTFail
调用是否会影响其他测试用例,尽管测试用例的等待限制已经用完?以上是关于XCTAssert/XCTFail 在异步回调中是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章