XCUITest: що це, принципи роботи та UI-тестування iOS

Автор: IT Sectr Опубліковано: 2026-04-09 Час читання: 8 хв

XCUITest — це фреймворк Apple для UI-тестування iOS, iPadOS та macOS додатків, вбудований безпосередньо в XCTest та Xcode. Він дозволяє симулювати дії користувача: натискання, введення тексту, свайпи, скрол та жести — з доступом до внутрішнього стану елементів інтерфейсу. За даними Apple Developer Documentation, 2025, XCUIApplication є точкою входу для всіх UI-тестів та надає доступ до ієрархії елементів екрану.

Головне

  • XCUITest — нативний фреймворк Apple для UI-тестування, вбудований у Xcode
  • Підхід білої скриньки забезпечує доступ до Accessibility-атрибутів та ієрархії елементів
  • Тести пишуться на Swift або Objective-C в інтеграції з XCTest
  • Запис тестів доступний через вбудований рекордер у Xcode
  • Запуск виконується на симуляторі iOS або реальному пристрої без додаткових серверів

Що таке XCUITest

XCUITest — це фреймворк для UI-тестування, випущений Apple у Xcode 7 (2015 рік). Він замінив UI Automation (UIA) та став стандартним інструментом для автоматизованого тестування інтерфейсу на платформах Apple. XCUITest повністю інтегрований у XCTest — єдиний тестовий фреймворк Apple.

Відмінність від Unit-тестів XCTest

На відміну від юніт-тестів, які перевіряють логіку на рівні класів та методів, XCUITest тестує користувацький інтерфейс через симуляцію дій. Тести запускаються в окремому процесі від додатка та взаємодіють із ним через Accessibility API — це забезпечує ізоляцію та надійність.

Переваги нативного підходу

XCUITest не вимагає встановлення сторонніх серверів (на відміну від Appium) та додаткових бібліотек для взаємодії з пристроєм. Все необхідне вже включено в Xcode. Це забезпечує найкращу сумісність з новими версіями iOS та миттєвий доступ до нових жестів та елементів керування.

Архітектура XCUITest та XCTest

Архітектура XCUITest побудована на двох ключових класах: XCUIApplication — запущений тестований додаток, та XCUIElement — елемент інтерфейсу. Тест-ранер XCTest керує життєвим циклом тестів: setUp, тестові методи, tearDown. XCUITest запускається як окремий процес, який керує додатком через Accessibility-міст.

Ієрархія елементів

Кожен елемент UI представлений об’єктом XCUIElement, який містить методи для запиту стану (exists, isHittable, label, value) та дій (tap, pressForDuration, swipeUp, typeText). Елементи організовуються в ієрархію через Query-ланцюжки: app.buttons[].staticTexts[].tables[]. Це дозволяє гнучко знаходити будь-який елемент на екрані.

Accessibility та локатори

XCUITest використовує атрибути Accessibility для ідентифікації елементів: accessibilityIdentifier — програмний ідентифікатор, та accessibilityLabel — опис для VoiceOver. Рекомендується задавати accessibilityIdentifier у коді додатка — це робить тести стабільними незалежно від локалізації та верстки.

Написання UI-тестів на XCUITest

Тести XCUITest пишуться на Swift з використанням синтаксису XCTest. Кожен тестовий клас успадковується від XCTestCase та містить методи, що починаються з test. У методі setUp запускається додаток з потрібною конфігурацією, а в tearDown виконується очищення та завершення сесії.

Базовий тестовий сценарій

Типовий тест: знайти елемент → виконати дію → перевірити результат. Пошук елемента здійснюється через дочірні запити XCUIElementQuery: app.buttons["loginButton"], app.textFields["email"]. Дії: .tap(), .typeText("text"), .swipeUp(). Перевірки: XCTAssertTrue(element.exists) або XCTAssertEqual(element.label, "expected").

swift
import XCTest

class LoginTests: XCTestCase {
    let app = XCUIApplication()

    override func setUp() {
        continueAfterFailure = false
        app.launch()
    }

    func testLoginWithValidCredentials() {
        let emailField = app.textFields["emailInput"]
        emailField.tap()
        emailField.typeText("user@test.com")

        let passwordField = app.secureTextFields["passwordInput"]
        passwordField.tap()
        passwordField.typeText("password123")

        app.buttons["loginButton"].tap()

        let homeLabel = app.staticTexts["homeTitle"]
        XCTAssertTrue(homeLabel.exists)
    }
}

Очікування та синхронізація

XCUITest підтримує явні очікування через XCTWaiter та предикати NSPredicate. Наприклад, очікування появи елемента протягом 5 секунд: XCTWaiter().wait(for: [expectation], timeout: 5). На відміну від Detox, XCUITest не має автоматичної синхронізації з мережевими запитами.

swift
// Очікування появи елемента з таймаутом
let expectedElement = app.staticTexts["welcomeMessage"]
let existsPredicate = NSPredicate(format: "exists == true")
let expectation = XCTNSNotificationExpectation(object: expectedElement)
let result = XCTWaiter().wait(
    for: [expectation], timeout: 5
)
XCTAssertEqual(result, .completed)

Розширені можливості XCUITest

XCUITest підтримує тестування складних сценаріїв: мультитач-жести, push-сповіщення, Deep Links, SFSafariViewController та міжпрограмну взаємодію. Siri-інтенти також можуть бути протестовані через XCUITest з використанням Siri Remote simulation.

Тестування жестів

XCUITest підтримує всі популярні жести: tap, doubleTap, pressForDuration, swipeUp/Down/Left/Right, pinch, rotate, twoFingerTap. Для складних сценаріїв використовується XCUIGesture з довільними координатами та тривалістю. Це дозволяє тестувати кастомні жести, такі як малювання або drag-and-drop.

Перехоплення мережевих запитів

Починаючи з Xcode 12, XCUITest підтримує перехоплення мережевих запитів через XCTestExpectation та URLProtocol. Це дозволяє тестувати додаток в офлайн-режимі або з підміненими відповідями сервера без модифікації коду додатка.

XCUITest у CI/CD

XCUITest запускається в CI-середовищах через xcodebuild з флагом test. Для паралельного запуску на кількох симуляторах використовується xcodebuild -testPlan з налаштуванням паралельного виконання в схемі Xcode. GitHub Actions, Bitrise та Jenkins мають вбудовану підтримку XCUITest.

Конфігурація для CI

Для CI потрібно налаштувати code signing, provisioning profiles та вказати дестинейшн (симулятор або пристрій). iOS-тести на симуляторі не вимагають сертифікатів. Для реальних пристроїв необхідний автоматичний підпис через Xcode Cloud або Fastlane.

bash
# Запуск XCUITest на симуляторі через xcodebuild
xcodebuild test \
  -project MyApp.xcodeproj \
  -scheme MyApp \
  -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' \
  -resultBundlePath ./TestResults \
  -parallel-testing-enabled YES \
  -parallel-testing-worker-count 4

Тестування Accessibility через XCUITest

XCUITest тісно пов’язаний з Accessibility API Apple, оскільки пошук елементів заснований на accessibility-атрибутах. Accessibility-тестування — це не лише спосіб пошуку елементів, але й перевірка доступності додатка для людей з обмеженими можливостями. XCUITest може перевіряти accessibilityLabel, traits та hints.

Перевірка VoiceOver

VoiceOver — екранний диктор Apple для незрячих користувачів. XCUITest дозволяє перевірити: accessibilityLabel — чи описаний елемент зрозумілим текстом, accessibilityTraits — чи відповідає тип елемента (кнопка, заголовок, зображення), та accessibilityHint — чи дає підказку про результат дії. Ці перевірки обов’язкові для публікації в App Store, і XCUITest автоматизує їх у складі регресійного прогону.

Автоматична перевірка Accessibility

Починаючи з Xcode 15, XCUITest підтримує вбудовану перевірку Accessibility через XCTAttachment з типом accessibilityAudit. Тест автоматично повідомляє про елементи з недостатньою контрастністю, непідписані зображення та некоректні traits. Це замінює ручний Accessibility Inspector.

swift
// Accessibility audit в XCUITest
func testAccessibilityAudit() {
    let app = XCUIApplication()
    app.launch()

    let audit = XCTAttachment(accessibilityAudit: app)
    add(audit)

    // Перевірка конкретного елемента
    let button = app.buttons["submitButton"]
    XCTAssertTrue(button.label.count > 0)
    XCTAssertTrue(button.isAccessibilityElement)
}

Performance-тести в XCUITest

XCUITest підтримує вимірювання продуктивності UI через XCTOSSignpostMetric та XCUIApplication.metrics. Можна виміряти час запуску додатка (launch time), швидкість навігації, час відгуку на жести. Performance-тести запускаються з вимірюванням baseline та автоматично падають при перевищенні порогу. Це дозволяє запобігти регресіям продуктивності до того, як вони потраплять до користувачів у релізній збірці.

Налаштування baseline

Baseline — це еталонний час виконання тесту. Xcode запам’ятовує baseline для кожного тесту на конкретній моделі пристрою та версії iOS. Якщо новий запуск перевищує baseline на заданий відсоток (за замовчуванням 10%), тест вважається таким, що впав. Для оновлення baseline використовується команда Edit Baseline у звіті тестів. Важливо перераховувати baseline при оновленні версії iOS або зміні моделі пристрою для CI-ферми.

Моніторинг стабільності тестів

Для відстеження стабільності XCUITest-тестів використовуються флаги: continueAfterFailure (чи продовжувати тест після першого падіння) та тестові плани Xcode з конфігураціями повторів. Рекомендується налаштовувати автоматичний перезапуск тестів, що впали (retry) — до 3 спроб для флапаючих тестів, пов’язаних з таймінгами анімацій або мережевими затримками.

Тестування push-сповіщень та Deep Links

XCUITest підтримує тестування push-сповіщень та Deep Links через springboard та launchArguments. Для push-сповіщень використовується XCUIApplication().launchArguments з параметром -UNUserNotificationCenter та відправка через XCTest. Deep Links тестуються через open URL із зазначенням кастомної схеми — XCUITest перехоплює системний діалог та перевіряє, чи відкрився додаток з правильним екраном. Для тестування сценарію відповіді на сповіщення використовується XCUIApplication().springboard, який симулює натискання на банер сповіщення в центрі сповіщень iOS. Ці сценарії критично важливі для додатків з диплінками та push-кампаніями, де потрібно перевірити коректність обробки зовнішніх викликів.

Інтеграція з Instruments

Для детального профілювання продуктивності XCUITest інтегрується з Instruments. Під час тесту можна запустити профілювання Time Profiler, Core Animation або Leaks через XCTMetric. Результати профілювання зберігаються у звіті та доступні для аналізу в Xcode. Це особливо корисно при оптимізації часу запуску додатка, навігації між екранами та продуктивності анімацій — типових вузьких місць в iOS-додатках.

Часто задавані питання

У чому різниця між XCUITest та XCTest?

XCTest — це загальний фреймворк для всіх типів тестів Apple, включаючи юніт-тести та performance-тести. XCUITest — це надбудова над XCTest для UI-тестування, яка додає класи XCUIApplication, XCUIElement та XCUIElementQuery для взаємодії з інтерфейсом.

Чи можна використовувати XCUITest з Objective-C?

Так, XCUITest підтримує як Swift, так і Objective-C. Однак більшість прикладів та документації Apple пишеться на Swift. Objective-C-проекти можуть використовувати XCUITest без додаткових налаштувань — фреймворк доступний через @import XCTest.

Як XCUITest знаходить елементи на екрані?

XCUITest використовує Accessibility API Apple. Елементи знаходяться за accessibilityIdentifier, accessibilityLabel, типом (button, textField, staticText) або положенням в ієрархії. Чим точніше задані Accessibility-атрибути в коді додатка, тим стабільніші тести.

Чи підтримує XCUITest запис тестів?

Так, Xcode включає вбудований рекордер UI-тестів. При запуску тесту в режимі запису Xcode фіксує всі взаємодії з інтерфейсом та генерує Swift-код. Записаний код можна доопрацювати: додати перевірки, винести в Page Objects та параметризувати.

Як запускати XCUITest на реальному пристрої?

Для запуску на реальному пристрої необхідно: підключити пристрій до Mac, додати його в Apple Developer Program, налаштувати provisioning profile, підписати додаток development-сертифікатом та вибрати пристрій як дестинейшн у xcodebuild.

Підсумки

  • XCUITest — нативний фреймворк Apple для UI-тестування iOS, iPadOS та macOS додатків
  • Інтеграція з Xcode забезпечує запис тестів, паралельний запуск та built-in звіти
  • XCUIApplication та XCUIElement — ключові класи для взаємодії з додатком
  • Accessibility-атрибути використовуються як надійні локатори, стабільні при змінах верстки
  • Очікування реалізуються через XCTWaiter та NSPredicate — автоматичної синхронізації немає
  • CI/CD підтримується через xcodebuild з паралельним запуском на симуляторах
  • Розширені сценарії включають мультитач, Siri Intents, перехоплення мережевих запитів та Deep Links

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також