Привет, Хабр!
В прошлой статье мы разобрались:
Что такое ui-тесты и для чего они нужны;
Как настроить окружение для тестов;
Как находить ui-элементы в проекте и проставлять им accessibilityidentifier.
В этой статье мы разберем:
Как обращаться и инициализировать ui-элементы в ваших тестах;
Как взаимодействовать с ui-элементами приложения;
Как писать ассерты для проверки в автотесте ожидаемого результата.
При наличии айдишника у ui-элемента, достаточно указать его при обращении.
XCUIApplication().buttons["Help"]
Если же у вас нет id у элемента, есть способ найти его при помощи XCUIElementQuery. Этот класс позволяет искать элемент несколькими способами.
// Находит все кнопки внутри scroll view (отобразит кнопки только прямого потомка scroll view)
XCUIApplication().scrollViews["Main"].children(matching: .button)
// Находит все кнопки внутри scroll view (отобразит кнопки прямого потомка scroll view, но также и его потомков)
XCUIApplication().scrollViews["Main"].descendants(matching: .button)
// Находит четвертую кнопку на экране
XCUIApplication().buttons.element(boundBy: 3)
// Находит в scroll view ui-элемент содержащий label = identifier
XCUIApplication().scrollViews["Main"].containing(NSPredicate(format: "label == %@","identifier").element
// Находит первую кнопку на экране
XCUIApplication().buttons.firstMatch
Немного про NSPredicate — это класс, который позволяет фильтровать объекты по нужному вам условию. Статья с хорошим объяснением как использовать NSPredicate.
Пример иницилизации переменной:
let moneyTitle: XCUIElement = XCUIApplication().staticTexts["accessibilityID"]
Вы можете в своих тестах совершать: нажатие, удержание и drag&drop ui-элементов.
Перечень методов можно посмотреть здесь, раздел — Tapping and Pressing.
// Совершаем нажатие на ui-элемент
XCUIApplication().buttons.element.tap()
// Cовершаем двойное нажатие на ui-элемент
XCUIApplication().buttons.element.doubleTap()
// Удерживаем нажатие в течение времени, которое передали в forDuration
XCUIApplication().buttons.element.press(forDuration: 3)
// Совершаем нажатие на ui-элемент и затем перетаскиваем его к другому ui-элементу
XCUIApplication().buttons.element.press(forDuration: 3, thenDragTo: XCUIApplication().searchFields.element)
Вы можете вводить текст по букве обращаясь к системной клавиатуре:
XCUIApplication().textFields.element.tap()
XCUIApplication().keys["h"].tap()
XCUIApplication().keys["e"].tap()
XCUIApplication().keys["l"].tap()
XCUIApplication().keys["p"].tap()
Либо вводить целую строку:
XCUIApplication().textFields.element.typeText("help")
Вы можете совершать множественные нажатия в своих тестах.
// Совершаем нажатие двумя пальцами на ui-элемент
XCUIApplication().buttons.element.twoFingerTap()
/*
Совершаем нажатие на элемент столько раз сколько передали
в withNumberOfTaps и столькими "пальцами" сколько передали
в numberOfTouches
*/
XCUIApplication().buttons.element.tap(withNumberOfTaps: 1, numberOfTouches: 1)
Перечень методов можно посмотреть здесь, раздел — Multiple Taps.
Вы можете совершать разные жесты в своих тестах.
// Совершаем свайп в указанном направлении
swipeLeft()
swipeRight()
swipeUp()
swipeDown()
// Совершаем свайп в указанном направлении с заданной скоростью
swipeLeft(velocity: 0.5)
swipeRight(velocity: 0.5)
swipeUp(velocity: 0.5)
swipeDown(velocity: 0.5)
// Совершаем приближения ui-элемента (withScale указываем больше 1)
XCUIApplication().images.element(boundBy: 0).pinch(withScale: 2, velocity: 1)
// Совершаем отдаления ui-элемента (withScale указываем от 0 до 1)
XCUIApplication().images.element(boundBy: 0).pinch(withScale: 0.5, velocity: 1)
// Совершаем вращение ui-элемента
XCUIApplication().images.element(boundBy: 0).rotate(0.5, withVelocity: 0.5)
Перечень методов можно посмотреть здесь, раздел — Performing Gestures.
UISlider — это элемент управления для выбора одного значения из диапазона значений.
Когда мы хотим изменить положение ползунка в слайдере, мы не передаем значение, которое хотим установить. Вместо этого мы выбираем число в диапазоне от 0 до 1. Где 0 — это минимальное значение в слайдере, а 1 — максимальное. Представим, что у нас есть слайдер с максимальным значением 100 и нам нужно сдвинуть ползунок на значение 25. Это будет выглядеть так:
XCUIApplication().sliders.element.adjust(toNormalizedSliderPosition: 0.25)
UIPickerView и UIDatePicker — это ui-элементы, которые используют “колесики” для выбора необходимых значений.
XCUIElement имеет специальный метод для взаимодействия с UIPickerView и UIDatePicker:
Для пикеров с одним колесом, мы можем получить доступ через element(), и указать значение, которое хотим выбрать;
Для пикеров с несколькими колесами, мы можем обратиться к нужному колесу по индексу и указать значение, которое хотим выбрать.
// Пикер с одним колесом
XCUIApplication().pickerWheels.element.adjust(toPickerWheelValue: "BMW")
// Пикер с несколькими колесами
XCUIApplication().pickerWheels.elementBoundByIndex(0).adjust(toPickerWheelValue: "BMW")
XCUIApplication().pickerWheels.elementBoundByIndex(1).adjust(toPickerWheelValue: "X6")
Системный алерт — это объект, отображающий предупреждающее сообщение для пользователя.
Чтобы взаимодействовать с ним, вам понадобится использовать метод addUIInterruptionMonitor(withDescription:handler:)
Где вы передаете:
withDescription — заголовок алерта;
handler – действие, которое хотите совершить.
Пример использования в тестах:
addUIInterruptionMonitor(withDescription: "Current Location Not Available") { alert in
alert.buttons["OK"].tap()
return true
}
Navigation bar — это панель навигации, отображается в верхней части экрана приложения под status bar и позволяет перемещаться по приложению.
Представим, что у нас есть две кнопки и текст по середине в Navigation Bar.
Вот пример того как можно их иницилизировать и в дальнейшем с ними взаимодействовать:
// Иницилизируем крайнюю левую кнопку в Navigation bar
let leftNavBarButton = XCUIApplication().navigationBars.children(matching: .button).firstMatch
// Иницилизируем тест посередине в Navigation bar
let topicNavBar = XCUIApplication().navigationBars.children(matching: .staticTexts).firstMatch
// Иницилизируем крайнюю правую кнопку в Navigation bar
let rightNavBarButton = XCUIApplication().navigationBars.children(matching: .button).element(boundBy: 1)
// Нажимаем на кнопки в Navigation bar
leftNavBarButton.tap()
rightNavBarButton.tap()
// Проверяем заголовок в Navigation bar
XCTAssertEqual(topicNavBar.title, "Topic")
Tab bar — это панель вкладок, отображается в нижней части экрана приложения. Она даёт возможность быстро переключаться между различными разделами приложения.
Для переключения между вкладками достаточно тапать на индекс элемента в Tab bar.
// Открываем первую вкладку
XCUIApplication().tabBars.buttons.element(boundBy: 0)
// Открываем третью вкладку
XCUIApplication().tabBars.buttons.element(boundBy: 2)
Ассерты — это проверки необходимого условия.
Рассмотрим несколько вариантов их использования:
// Ассерт, что кнопка отображается на экране
XCTAssertTrue(XCUIApplication().buttons["Warning"].exists)
// Ассерт, что кнопка не выделена
XCTAssertFalse(XCUIApplication().buttons["Warning"].isSelected)
// Ассерт, что title кнопки равен - Buy
XCTAssertEqual(XCUIApplication().buttons.element.title, "Buy")
// Ассерт, что placeholder в textFields не равен - placeHolder
XCTAssertNotEqual(XCUIApplication().textFields.element.placeholderValue, "placeHolder")
// Ассерт, что value в textFields равно - value
XCTAssertEqual(XCUIApplication().textFields.element.value, "value")
Полный перечень возможных ассертов можно посмотреть здесь, раздел Test Assertions
Перечень возможных атрибутов ui-элементов можно посмотреть здесь
Взаимодействовать с ui-элементами во время теста не так сложно, как кажется на первый взгляд. Воспользовавшись примерами выше, можно быстро добавить необходимые методы в свой проект с ui-тестами.
В следующей статье мы расскажем про жизненый цикл тестового приложения:
Как делать предусловия и послеусловия;
Как сбрасывать статус пермишенов приложения перед запуском тестов (доступ к галерее, фото и так далее);
Как запускать приложения по bundle identifier (например запуск сафари, документов и так далее);
И многое другое.
Центр управления связью общего пользования (ЦМУ ССОП) Роскомнадзора рекомендовал компаниям из реестра провайдеров ограничить доступ поисковых ботов к информации на российских сайтах.…
Apple возобновила переговоры с OpenAI о возможности внедрения ИИ-технологий в iOS 18, на основе данной операционной системы будут работать новые…
Конкурсный управляющий российской «дочки» Google подготовил 23 иска к участникам рекламного рынка. Общая сумма исков составляет 16 млрд рублей –…
Google завершил обновление основного алгоритма March 2024 Core Update. Раскатка обновлений была завершена 19 апреля, но сообщил об этом поисковик…
У частных продавцов на Авито появилась возможность составлять текст объявлений с помощью нейросети. Новый функционал доступен в категории «Обувь, одежда,…
24 апреля 2024 года в Москве состоялась церемония вручения наград международного конкурса Workspace Digital Awards. В этом году участниками стали…