我的导航栏为"添加"按钮就可以了,我需要让Xcode的UI测试点击该按钮,在它打开的视图控制器中执行测试。我以编程方式添加按钮:
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(showAddVC)];
self.navigationItem.rightBarButtonItem = addButton;
在我的测试中,我有:
XCUIApplication *app = [[XCUIApplication alloc] init];
XCTAssert([app.buttons[@"Add"] exists]); // <-- This passes, so the test runner does see the button.
但是当我尝试使用其中任何一个来点击它时:
// Generated using the test recorder
[app.navigationBars[@"App Title"].buttons[@"Add"] tap];
或:
// Same expression used with the XCTAsset earlier
[app.buttons[@"Add"] tap];
什么都没发生。点击按钮时应该执行的操作不会发生。我尝试在行之间添加一些sleep(5)
来让应用加载,但这并没有多大帮助。
这是测试日志:
Test Case '-[xx]' started.
t = 0.00s Start Test
t = 0.00s Set Up
2015-12-22 16:25:02.898 XCTRunner[10978:384690] Continuing to run tests in the background with task ID 1
t = 0.94s Launch xx
t = 1.01s Waiting for accessibility to load
t = 3.45s Wait for app to idle
t = 9.02s Tap "Add" Button
t = 9.02s Wait for app to idle
t = 39.07s Assertion Failure: UI Testing Failure - App failed to quiesce within 30s
xx: error: -[xx] : UI Testing Failure - App failed to quiesce within 30s
答案 0 :(得分:5)
上述答案都不适合我。经过几个小时的奋斗之后,最终使它发挥作用的是重复敲击。试试这个:
[app.navigationBars[@"App Title"].buttons[@"Add"] tap];
[app.navigationBars[@"App Title"].buttons[@"Add"] tap];
虽然上面最初对我有用,但我发现有时第一个水龙头工作,这将导致两个水龙头。我的解决方案是改为点击在UI测试开始时不会触发任何操作的任意UI元素,然后正常进行。我认为第一次点击适用于某些设备,或者可能是在第一次UI测试运行之后。
答案 1 :(得分:1)
在您的情况下,exists
的测试似乎不够。在尝试点击按钮之前,请等待按钮hittable
。
expectationForPredicate(predicate, evaluatedWithObject: element, handler: nil)
waitForExpectationsWithTimeout(timeoutSeconds, handler: nil)
在你的情况下会是:
expectationForPredicate(NSPredicate(format: "hittable == YES"), evaluatedWithObject: [app.buttons[@"Add"], handler: nil)
waitForExpectationsWithTimeout(15, handler: nil)
[app.buttons[@"Add"] tap];
这将暂停waitForExpectationWithTimeout
之后的代码执行,直到该谓词对给定元素满意为止。
否则,在极端情况下,我发现在尝试与某些组件交互时有时会发生错误。这些发生的方式,原因和时间有点神秘,但它们似乎与某些组件有些一致,涉及UINavigationBars的事情似乎更频繁地发生。
为了克服这些问题,我发现使用此扩展程序有时会有效。
extension XCUIElement {
/* Sends a tap event to a hittable/unhittable element. Needed to get past bug */
func forceTapElement() {
if hittable {
tap()
}
else {
let coordinate: XCUICoordinate = coordinateWithNormalizedOffset(CGVectorMake(0.0, 0.0))
coordinate.tap()
}
}
}
答案 2 :(得分:1)
对于Alex的回答不起作用的人,请尝试:
extension XCUIElement {
func forceTap() {
coordinate(withNormalizedOffset: CGVector(dx:0.5, dy:0.5)).tap()
}
}
我刚遇到UIWebView
的问题,这个问题是可以触及的,但是直到通过坐标完成它才开始工作
答案 3 :(得分:0)
一种可能性是您的条形按钮项目推送具有刷新控件的新视图控制器 - 您可能只在iPad上遇到此情况,只有您的条形按钮项目会推到拆分视图控制器的细节部分。获取项目后,您可能会停止刷新控件,而这些控件首先不会刷新。 Xcode的自动化确实可以解决这个问题,睡眠/超时也无济于事。
因此,要解决此问题,请在主应用程序上,在结束刷新之前始终检查刷新控件是否刷新。我也想首先检查一下它是不是nil:如果你使用的是Swift,if-let where
一下子做了所有这些,那么你的朋友应该在这里:
if let refresh = self.refreshControl where refresh.refreshing {
refresh.endRefreshing()
}