我正在使用Xcode7 / iOS 9中引入的XCUIApplication,XCUIElement和XCUIElementQuery为我的应用程序编写UI测试用例。
我遇到了路障。测试用例中的一个屏幕需要iOS的位置服务。正如预期的那样,系统会提示用户允许使用位置服务,其标题为:Allow “App name” to access your location while you use the app?
Allow
& Don't Allow
个按钮。
问题似乎是左右,因为警报由操作系统本身呈现,因此它不存在于应用程序的元素子树中。
我记录了以下内容:
print("XYZ:\(app.alerts.count)")//0
var existence = app.staticTexts["Allow “App Name” to access your location while you use the app?"].exists
print("XYZ:\(existence)")//false
existence = app.buttons["Allow"].exists
print("XYZ:\(existence)") //false
即使是UI录制也生成了类似的代码:
XCUIApplication().alerts["Allow “App Name” to access your location while you use the app?"].collectionViews.buttons["Allow"].tap()
我没有找到任何可以让我解决这个问题的API。例如:
那么我怎么能超越这个呢?有没有办法配置测试目标,以便不需要位置服务授权。
答案 0 :(得分:29)
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let allowBtn = springboard.buttons["Allow"]
if allowBtn.exists {
allowBtn.tap()
}
_ = addUIInterruptionMonitor(withDescription: "Location Dialog") { (alert) -> Bool in
alert.buttons["Allow"].tap()
return true
}
app.buttons["Request Location"].tap()
app.tap() // need to interact with the app for the handler to fire
请注意,它有点不同,因为方法名称现在是addUIInterruptionMonitor并将withDescription作为参数
Xcode 7.1最终修复了系统警报的问题。然而,有两个小问题。
首先,您需要在显示警报之前设置“UI Interuption Handler”。这是告诉框架如何处理警报的方式。
其次,在显示警报后,您必须与界面进行交互。只需点击应用程序就可以了,但是是必需的。
addUIInterruptionMonitorWithDescription("Location Dialog") { (alert) -> Bool in
alert.buttons["Allow"].tap()
return true
}
app.buttons["Request Location"].tap()
app.tap() // need to interact with the app for the handler to fire
“位置对话框”只是一个字符串,可以帮助开发人员识别访问哪个处理程序,而不是特定于警报类型。
以下内容将消除Xcode 7 Beta 6中的单个“系统警报”:
let app = XCUIApplication()
app.launch()
// trigger location permission dialog
app.alerts.element.collectionViews.buttons["Allow"].tap()
Beta 6为UI测试引入了一系列修复程序,我相信这是其中之一。
另请注意,我直接在-element
上致电-alerts
。在-element
上调用XCUIElementQuery
会强制框架在屏幕上选择“唯一的”匹配元素。这适用于一次只能显示一个警报的警报。但是,如果您为标签尝试此操作并且有两个标签,则框架将引发异常。
答案 1 :(得分:7)
这是唯一对我有用的东西。使用Xcode 9 fwiw。
也可能与我已经使用addUIInterruptionMonitor
用于其他警报相关。我尝试重新排序它们并没有什么区别。当你有两个时,可能是9中的问题,或者可能是我错误地使用它们。无论如何,下面的代码都有效。 :)
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let allowBtn = springboard.buttons["Allow"]
if allowBtn.exists {
allowBtn.tap()
}
答案 2 :(得分:3)
如果要检查警报是否显示,只需检查是否存在按钮:
if (app.alerts.element.collectionViews.buttons["Dismiss"].exists)
{
app.alerts.element.collectionViews.buttons["Dismiss"].tap()
}
检查警报是否正在显示,如果显示警报则会点击
答案 3 :(得分:3)
我可以在 Xcode 9.4.1 上使用它,诀窍是等待弹出窗口出现。
// wait for location service popup to appear
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let allowBtn = springboard.buttons["Allow"]
expectation(for: NSPredicate(format: "exists == true"), evaluatedWith: allowBtn, handler: nil)
waitForExpectations(timeout: 10, handler: nil)
//allow location service
if allowBtn.exists {
allowBtn.tap()
}
答案 4 :(得分:2)
在xcode 9.1上,仅在测试设备具有iOS 11 时才会处理警报。不适用于较旧的iOS版本,例如10.3等。参考:https://forums.developer.apple.com/thread/86989
要处理警报,请使用:
x = parseInt(x);
y = parseInt(y);
var z1 = 0;
var z2 = 0;
...
z1=x+1:
z2=y;
...
array[z1][z2] = 10;
答案 5 :(得分:1)
这适用于所有语言:
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let allowBtn = springboard.buttons.element(boundBy: 2)
if allowBtn.exists {
allowBtn.tap()
}
答案 6 :(得分:0)
要点按允许位置提醒,您可以拨打电话 element.tap()其中element是屏幕上的任何元素。 因此,在调用tap后,辅助功能将点击“在提醒状态下允许”而不是点按您的元素
答案 7 :(得分:0)
这是我通过点击(两个按钮)对话框中找到的第二个按钮来接受任何语言的通知权限警报的方法。 “允许”按钮在右侧,因此索引为1。
let handler = addUIInterruptionMonitor(withDescription: "System Dialog") { (alert) -> Bool in
alert.buttons.element(boundBy: 1).tap()
return true
}
app.tap()