XCTAssert/XCTFail 在异步回调中是不是安全?

Posted

技术标签:

【中文标题】XCTAssert/XCTFail 在异步回调中是不是安全?【英文标题】:Are XCTAssert/XCTFail safe in async callbacks?XCTAssert/XCTFail 在异步回调中是否安全? 【发布时间】:2018-07-20 03:30:20 【问题描述】:

我经常看到在理论上等待期望时在调用的回调中使用XCTAssertXCTFail 的示例。如果超时到期,会发生什么?

一个人为的例子(随意考虑 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 在异步回调中是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter的异步回调

Flutter的异步回调

scrapy补充-异步爬虫

setState是同步的还是异步的

Redux 中的 store.dispatch 是同步的还是异步的

php支付宝手机网站支付,异步回调和同步回调里面应该怎么写