gpt4 book ai didi

ios - Xcode 测试单独通过,与其他测试一起运行时失败

转载 作者:技术小花猫 更新时间:2023-10-29 10:26:17 28 4
gpt4 key购买 nike

我编写了一些带有 XCTest 期望的异步单元测试来测试我编写的网络类。我的大部分测试每次都有效。

有一些测试在我运行整个套件时失败了,但它们自己通过了。

其他测试失败,但使用相同 URL 的请求在粘贴到浏览器时会返回适当的数据。

我的网络代码封装在 NSOperation 对象中,这些对象在 NSOperationQueue 上运行。 (我的操作队列是默认类型——我没有明确地将底层 GCD 队列设置为串行或并发。)

我可以查看哪些内容来修复这些测试?看完this post on objc.io ,我假设他们遇到了某种隔离问题。

最佳答案

您走在正确的道路上。 objc.io 文章建议的解决方案可能是正确的方法,但确实需要一些重构。如果您想在进行代码更改狂潮之前首先通过测试,那么您可以按照以下方法进行操作。

通常,您可以使用 XCTestExpectations 来完成几乎所有的异步测试。标准模式可能是这样的:

XCTestExpectation *doThingPromise = [self expetationWithDescription:@"Bazingo"];
[SomeService doThingOnSucceed:^{
[doThingPromise fulfill];
} onFail:^ {
}];
[self waitForExpectationsWithTimeout:1.0 handler:^(NSError *error) {
expect(error).to.beNil();
}]

如果 [SomeService doThingOnSucceed:onFail:] 触发一个异步请求然后直接解析,这会很好地工作。但如果它做了更奇特的事情,比如:

+ (void)doThingOnSucceed:onFail: {
[Thing do it];
[self.context performBlock:^{
// Uh oh Farfalle-Os
success();
}];
}

执行 block 将被设置,但您不会等待它完成,因为您实际上不是在等待内部 block ,而是等待外部 block 。关键是 XCTestWaits 实际上让测试完成,然后检查 promise 是否在某个时间段内实现,但与此同时它将开始运行其他测试。 success() 可以出现在任意数量的地方并产生任意数量的奇怪行为。

隔离行为(相对于无隔离)来自这样一个事实:如果你只运行这个测试,一切可能都很好,但如果你运行多个测试,那么 CoreData block 可能只是停留在下一个测试之前async,然后它将“解除阻塞”它的执行,它将在未来某个随机时间开始执行,以进行一些随机的 future 测试。

短期明确的 hack around 是暂停您的测试,直到事情完成。这是一个例子:

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[SomeService doThingOnComplete:^{
dispatch_semaphore_signal(semaphore);
}];
while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW)) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];
}

这明确地阻止了一个测试在一切都完成之前完成,这意味着在这个测试完成之前没有其他测试可以运行。

如果您的测试/代码中有很多这样的情况,我会推荐 objc.io 解决方案,即创建一个您可以在每次测试后等待的调度组。

关于ios - Xcode 测试单独通过,与其他测试一起运行时失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28076986/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com