Взаимодействие с alerts и permissions в ui-тестировании iOS

от автора

Привет, Хабр!

Меня зовут Ахмат. Я iOS QA Automation Engineer — в Vivid Money.

В этой статье я хочу рассказать про взаимодействие с alerts и permissions в iOS тестах и показать, как их можно эффективно обрабатывать в своём проекте.

Данная статья будет полезна начинающим iOS-автоматизаторам, либо разработчикам, которые решили изучить XCUITest и покрыть свой проект ui-тестами.

В рамках статьи мы разберем:

  • Что такое alerts и permissions вашего iOS приложения;

  • Как обрабатывать alerts в коде теста, где они являются частью сценария;

  • Как автоматически обрабатывать permissions;

  • Как реализовать механизм включения и выключения alerts и permissions с помощью передачи аргументов при запуске тестов.

Что такое alerts и permissions?

Alerts — дают возможность предоставлять пользователям критически важную информацию.
Например, alert может сообщать пользователю, что приложение запрашивает разрешение на отправку им нотификаций, и давать им возможность подтвердить или отклонить. Alerts появляются при первичном запуске вашего приложения.

Permissions — позволяют приложениям запрашивать разрешение на использование настроек конфиденциальности. Например таких, как Location Services для определения вашего точного местоположения.

Permissions появляются при первичном входе в раздел, к которому требуется запросить у вас разрешение.

Как обрабатывать alerts?

Способы взаимодействия с alerts — сделать их частью сценария (онбординг/авторизация и т.д) и кликать на нужные кнопки из кода теста или делать отдельный тест в наборе, который явно запускается первым и проходит все alerts при первом запуске приложения.

Alerts находятся в иерархии текущего активного приложения, иногда это ваше тестируемое, иногда это springboard (встроенное приложение, которое управляет домашним экраном iOS).

let springBoardApp = XCUIApplication(     bundleIdentifier: "com.apple.springboard" )  let app = XCUIApplication()  if springBoardApp.alerts.buttons["Allow"].waitForExistence(timeout: 1) { springBoardApp.alerts.buttons["Allow"].tap() } else if app.alerts.buttons.element(boundBy: 1).waitForExistence(timeout: 1) { app.alerts.buttons["Allow"].tap() }

Наиболее эффективный способ — это обрабатывать alerts, когда они являются частью сценария.

Создание отдельного теста для обработки всех alerts при первичном запуске может привести к нестабильности прогона всего тестового набора. Зачастую может произойти сбой во время прокликивания alerts, что в последствии приведет к частичному падению следующих тестов в наборе.

Как автоматически обрабатывать permissions?

В тестовый проект нужно добавить монитор прерывания пользовательского интерфейса. В XCTest есть метод, addUIInterruptionMonitor() который мы можем использовать для мониторинга и реагирования на появление permissions.

addUIInterruptionMonitor(withDescription: "Tracking Usage Permission Alert") {     (alert) -> Bool in     if alert.buttons["Allow"].exists {         alert.buttons["Allow"].tap()         self.app.activate()         return true     }     return false     }

Наиболее эффективно вызывать addUIInterruptionMonitor() в начале теста, где мы точно знаем что по сценарию появится permission. Вызов обработчика в setUp() не будет отрабатывать автоматически на всех тестах. Так же для каждого permission нужен отдельный вызов монитора прерывания пользовательского интерфейса.

Как включать и выключать alerts и permissions с помощью передачи аргументов?

Можно включать появление alerts и permissions только в тех тестах, где они будут являться частью тестового сценария.

Потребуется реализовать механизм управления добавлением в инициализацию делегатов, отвечающих за alerts и permissions.

Реализуем механизм включения/выключения оповещения о трекинге активности. За появление диалогового окна трекинг менеджера в нашем приложении отвечает механизм ATTrackingManager.

Создадим расширение для XCUIApplication, где напишем функцию launch с возможностью передачи аргументов:

extension XCUIApplication {  func launch(arguments: [String] = ["TrackingManager"]) {     if state != .notRunning {         terminate()         launchArguments = []     }      launchArguments = arguments      launch()     _ = wait(for: .runningForeground, timeout: 10) }  }

Далее нам потребуется выяснить в каком делегате у нас реализован вызов диалогового окна трекинг менеджера. Достаточно в поиске ввести ATTrackingManager и взять название делегата.

final class AppsFlyerAppDelegate: NSObject, UIApplicationDelegate {      func applicationDidBecomeActive(_ application: UIApplication) {         // for iOS 13 and below - The IDFA will be collected by the SDK. The user will NOT be prompted for permission.         if #available(iOS 14, *) {             // Show the user the Apple IDFA consent dialog (AppTrackingTransparency)             // Can be called in any place             ATTrackingManager.requestTrackingAuthorization { _ in             }         }                  if let deviceId = CheckEmailAccessExperiment.obtainDeviceId(inPlace: "AppsFlyerInstance") {             appsFlyerInstance.customerUserID = deviceId         }                  appsFlyerInstance.start()     } }

Реализуем обработчик в AppDelegate и запуск ATTrackingManager в тестах, где аргумент “TrackingManager” не передается:

public class AppDelegate: UIResponder {          let pushNotificationsAppDelegate = PushNotificationsAppDelegate()     let appsFlyerAppDelegate = AppsFlyerAppDelegate()      private lazy var appDelegates: [UIApplicationDelegate] = {          var appDelegates: [UIApplicationDelegate] = [             pushNotificationsAppDelegate         ]                  if !ProcessInfo.processInfo.arguments.contains("TrackingManager") {             appDelegates.append(appsFlyerAppDelegate)         }                  return appDelegates     }()      }

Таким способом можно отключать все виды alerts и permissions по отдельности, как показано в примере выше или можно создать один общий аргумент для обработки добавления делегатов в appDelegates, отвечающий за все виды alerts и permissions.

Сочетая все три способа взаимодействия с alerts и permissions, можно сделать ваш код чистым и уменьшить число флаков при прогоне тесового набора.


ссылка на оригинал статьи https://habr.com/ru/company/vivid_money/blog/672586/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *