我正在编写UIAutomation测试用例,我需要等待用户激活才能继续。似乎不是检查按钮更改为启用状态的好方法。
最好是在用户界面中等待某些事情发生,然后再检查其状态?
dispatch_after和NSTimer似乎都不起作用。他们只是阻止然后失败。
答案 0 :(得分:5)
如果您使用NSPredicates和期望,这实际上非常简单。您甚至可以设置超时值。此示例显示如何使用5秒超时执行此操作。
let exists = NSPredicate(format:"enabled == true")
expectationForPredicate(exists, evaluatedWithObject: app.tables.textFields["MY_FIELD_NAME"], handler: nil)
waitForExpectationsWithTimeout(5, handler: nil)
答案 1 :(得分:1)
等待和检查元素的更好方法不是delay()
函数,而是pushTimeout()
函数。 Apple建议使用第二个功能。这是一个代码示例:
UIATarget.localTarget().pushTimeout(10)
button.tap()
UIATarget.localTarget().popTimeout()
Apple将反复尝试点击该按钮,并等待最多10秒钟。这是文档的link。
答案 2 :(得分:0)
Etienne's answer是正确的,但在我的情况下,它需要一些额外的内容。
我正在使用React Native,并且有一个<TouchableWithoutFeedback disabled={true}>
组件。但是我可以看到,每当XCUI尝试检查其状态时,它都将其视为已启用。确实,使用断点并检查element.IsEnabled
显然与我在UI中看到的内容矛盾。
使用AccessibilityState可以实现这一点,例如:
<TouchableWithoutFeedback
accessibilityState={{
disabled: this.props.disabled,
}}
>
具有RN 0.62.2的经验
答案 3 :(得分:-1)
默多克的答案是针对旧的JavaScript测试系统。我最终想出了这个:
https://gist.github.com/briandw/59bf5a06afe8af67a690
- (void)waitFor:(NSTimeInterval)seconds withExpectationBlock:(BOOL (^)())block
{
NSDate *timeoutDate = [[NSDate alloc] initWithTimeIntervalSinceNow:seconds];
while (YES)
{
if ([timeoutDate timeIntervalSinceNow] < 0 || !block())
{
return;
}
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
XCUIElement *nextButton = app.navigationBars[@"Title"].buttons[@"Next"];
XCTestExpectation *activationExpectation = [self expectationWithDescription:@"Waiting"];
[self waitFor:20.0 withExpectationBlock:^BOOL()
{
if (nextButton.exists && nextButton.enabled)
{
[activationExpectation fulfill];
return YES;
}
return NO;
}];
答案 4 :(得分:-3)
您应该能够实现while循环来检查所需的条件(例如,启用按钮)。这将停止测试用例进度,直到满足while条件并且测试将继续。建立一个延迟来减慢轮询,并确保你有一个超时,这样你就不会无限期地陷入困境。
<强>伪代码强>:
While (/*button is disabled*/) {
if (/*timeout condition met*/) {
/*handle error*/
break;
}
UIATarget.delay(<duration in seconds>);
}