2015-10-14 3 views
2

У меня есть тест пользовательского интерфейса, который включает в себя увольнение системного UIAlertController. Это предупреждение запрашивает у пользователя разрешение на доступ к календарю устройства. Целью теста является поведение после нажмите на кнопку OK:XCode 7 UI Тестирование: Увольнение системного UIAlertController не работает

1 let app = XCUIApplication() 
... 
// this code was basically generated by the recording feature of XCode 7 
2 app.alerts.elementBoundByIndex(0).collectionViews.buttons["OK"].tap() 

Теперь, вместо того, чтобы нажать на кнопку OK, линия 2 делает тренажер крана на первой кнопке, которая случается кнопку Cancel. ..

Кроме того, я узнал, что структура тестирования не точно распознает возникающее предупреждение. Так что, если я проверить текущее количество предупреждений я всегда получаю 0:

// ...tap... 
let count = app.alerts.count // == 0 

Это также происходит, если я использую NSPredicate для условия и ждать в течение нескольких секунд.

Возможно ли, что тесты пользовательского интерфейса не работают надежно с системными предупреждениями? Я использую XCode 7.0.1.

+0

Взаимодействие с системными предупреждениями через UI Testing [известная ошибка/проблема] (http://openradar.appspot.com/radar?id=4979891669827584). –

+0

OMG! Путешествие с обнаружением ошибок XCode 7 кажется бесконечной историей ... – Bastian

+0

Больше нет, woot! Проверьте [мой ответ ниже] (http://stackoverflow.com/a/33700623/384110). :-) –

ответ

0

мне удалось отклонить запрос доступа к контактам, как это:

let alert = app.alerts["\u{201c}******\u{201d} Would Like to Access Your Contacts"].collectionViews.buttons["OK"] 
if alert.exists 
{ 
    alert.tap() 
} 

Replace звездочек с названием приложения. Он может работать одинаково для календаря.

Это то, что я в конечном итоге с помощью, чтобы получить приглашение появляться, а затем разрешить доступ к Контакты:

func allowAccessToContacts(textFieldsName: String) 
{ 
    let app = XCUIApplication() 

    let textField = app.textFields[textFieldsName] 
    textField.tap() 
    textField.typeText("aaa") 

    let alert = app.alerts["\u{201c}******\u{201d} Would Like to Access Your Contacts"].collectionViews.buttons["OK"] 
    if alert.exists 
    { 
     alert.tap() 
    } 
    textField.typeText("\u{8}\u{8}\u{8}") 
} 
+0

К сожалению, это тоже не работает для меня. – Bastian

6

Xcode 7.1 наконец-то исправили проблему с предупреждениями системы. Есть, однако, две небольшие ошибки.

Во-первых, перед представлением предупреждения необходимо настроить «обработчик прерывания пользовательского интерфейса». Это наш способ рассказать о том, как обращаться с предупреждением, когда оно появляется.

Во-вторых, после представления предупреждения вы должны взаимодействовать с интерфейсом. Просто прослушивание приложения работает просто отлично, но это необходимо.

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 

«Местоположение Диалог» это просто строка, чтобы помочь разработчику определить, какой обработчик был доступ, это не относится к типу оповещения. Я считаю, что возврат true от обработчика означает его «полный», что означает, что он не будет вызываться снова.

+2

Вы пытались уволить несколько разных предупреждений в строке? Я пытаюсь понять это. Однако это сложнее, чем просто зарегистрировать несколько мониторов прерываний (в обратном порядке) –

+1

Joe, спасибо, что поделились этим. Как насчет последовательных предупреждений прямо при запуске? У меня есть запрос на местоположение, а затем сразу после этого для push-уведомлений. При вашем подходе я могу отбросить первый штраф, но второй не активирует 'addUIInterruptionMonitorWithDescription' снова. Есть идеи? – Lizza

+2

Я бы порекомендовал 'app.coordinateWithNormalizedOffset (CGVector (dx: 200, dy: 1)). Tap()' вместо 'app.tap() ', потому что он может щелкнуть что-то, чего вы не ожидаете, как в моем случае, и разорвать дальнейший тестовый поток. –