Lef*_*nia 12 unit-testing ios xcode6
我正在尝试更新我的异步单元测试以使用新XCTestExpectation接口而不是手动旋转运行循环.
我的单元测试之前使用的功能waitForBlock,finishBlock以及waitForTimeInterval:这很简单,称为一个方便的方法finishBlock在指定的时间之后.我正在尝试更新此设置以使用期望值.
使用waitForBlock+ finishBlock语义的测试在被替换为waitForExpectationsWithTime:handler:和之后都正常工作fulfill,但我的替换解决方案waitForTimeInterval:似乎不起作用.
- (void)waitForTimeInterval:(NSTimeInterval)delay
{
XCTestExpectation *expectation = [self expectationWithDescription:@"wait"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[expectation fulfill];
});
[self waitForExpectationsWithTimeout:delay + 1 handler:nil];
}
Run Code Online (Sandbox Code Playgroud)
编辑:
似乎代码实际上确实有效...所以这可能只是Xcode 6今天下午与我联系.
我觉得它应该是相当简单的:创建一个期望,设置一个满足的异步块,然后等待.但是,dispatch_after永远不会调用该块.
我的预感是waitForExpectationsWithTimeout:handler:阻塞它的当前线程,这是主队列,因此运行循环永远不会到达其异步块.这似乎是合理的,但我在提出实现此功能的不同方法时遇到了麻烦.
我正在寻找1)关于XCTestExpectation这可能揭示解决方法的其他信息,或2)实现此功能的不同想法.
dispatch_async(dispatch_get_main_queue(), ...)似乎在Xcode 7 UI Tests中不起作用,永远不会调用完成处理程序.performSelector在Swift中不再可用,但还有另外两种解决方法:
使用计时器
var waitExpectation: XCTestExpectation?
func wait(duration: NSTimeInterval) {
waitExpectation = expectationWithDescription("wait")
NSTimer.scheduledTimerWithTimeInterval(duration, target: self,
selector: Selector("onTimer"), userInfo: nil, repeats: false)
waitForExpectationsWithTimeout(duration + 3, handler: nil)
}
func onTimer() {
waitExpectation?.fulfill()
}
Run Code Online (Sandbox Code Playgroud)在全局队列上运行块(它可以工作,但可能不安全,因为它没有记录XCTestExpectation是线程安全的任何地方).
func wait(duration: NSTimeInterval) {
let expectation = expectationWithDescription("wait")
let dispatchTime = dispatch_time(DISPATCH_TIME_NOW,
Int64(duration * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
expectation.fulfill()
}
waitForExpectationsWithTimeout(duration + 3, handler: nil)
}
Run Code Online (Sandbox Code Playgroud)我已经在许多项目中使用XCTestExpectation来处理各种异步Web和GCD内容...... AFAIK,类似以下内容似乎是最常见的用法:
- (void)testExample {
// create the expectation with a nice descriptive message
XCTestExpectation *expectation = [self expectationWithDescription:@"The request should successfully complete within the specific timeframe."];
// do something asyncronously
[someObject doAsyncWithCompletionHandler:^(NSInteger yourReturnValue) {
// now that the async task it done, test whatever states/values you expect to be after this is
// completed
NSInteger expectedValue = 42;
XCTAssert(yourReturnValue == expectedValue, @"The returned value doesn't match the expected value.");
// fulfill the expectation so the tests can complete
[expectation fulfill];
}];
// wait for the expectations to be called and timeout after some
// predefined max time limit, failing the test automatically
NSTimeInterval somePredefinedTimeout = 3;
[self waitForExpectationsWithTimeout:somePredefinedTimeout handler:nil];
}
Run Code Online (Sandbox Code Playgroud)
显然使用performSelector:withObject:afterDelay:预期的作品,虽然我仍然不确定为什么.如果有人知道为什么GCD dispatch_after不起作用,请提供额外的答案,我会接受.目前,此设置似乎按预期工作:
- (void)waitForTimeInterval:(NSTimeInterval)delay
{
XCTestExpectation *expectation = [self expectationWithDescription:@"wait"];
[self performSelector:@selector(fulfillExpectation:) withObject:expectation afterDelay:delay];
[self waitForExpectationsWithTimeout:delay + 1 handler:nil];
}
- (void)fulfillExpectation:(XCTestExpectation *)expectation
{
[expectation fulfill];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9043 次 |
| 最近记录: |