XCUITest — это фреймворк Apple для UI-тестирования iOS, iPadOS и macOS приложений, встроенный непосредственно в XCTest и Xcode. Он позволяет симулировать действия пользователя: нажатия, ввод текста, свайпы, скролл и жесты — с доступом к внутреннему состоянию элементов интерфейса. По данным Apple Developer Documentation, 2025, XCUIApplication является точкой входа для всех UI-тестов и предоставляет доступ к иерархии элементов экрана.
Главное
XCUITest — это фреймворк для UI-тестирования, выпущенный Apple в Xcode 7 (2015 год). Он заменил UI Automation (UIA) и стал стандартным инструментом для автоматизированного тестирования интерфейса на платформах Apple. XCUITest полностью интегрирован в XCTest — единый тестовый фреймворк Apple.
В отличие от юнит-тестов, которые проверяют логику на уровне классов и методов, XCUITest тестирует пользовательский интерфейс через симуляцию действий. Тесты запускаются в отдельном процессе от приложения и взаимодействуют с ним через Accessibility API — это обеспечивает изоляцию и надёжность.
XCUITest не требует установки сторонних серверов (в отличие от Appium) и дополнительных библиотек для взаимодействия с устройством. Всё необходимое уже включено в Xcode. Это обеспечивает наилучшую совместимость с новыми версиями iOS и мгновенный доступ к новым жестам и элементам управления.
Архитектура XCUITest построена на двух ключевых классах: XCUIApplication — запущенное тестируемое приложение, и XCUIElement — элемент интерфейса. Тест-раннер XCTest управляет жизненным циклом тестов: setUp, тестовые методы, tearDown. XCUITest запускается как отдельный процесс, который управляет приложением через Accessibility-мост.
Каждый элемент UI представлен объектом XCUIElement, который содержит методы для запроса состояния (exists, isHittable, label, value) и действий (tap, pressForDuration, swipeUp, typeText). Элементы организуются в иерархию через Query-цепочки: app.buttons[].staticTexts[].tables[]. Это позволяет гибко находить любой элемент на экране.
XCUITest использует атрибуты Accessibility для идентификации элементов: accessibilityIdentifier — программный идентификатор, и accessibilityLabel — описание для VoiceOver. Рекомендуется задавать accessibilityIdentifier в коде приложения — это делает тесты стабильными независимо от локализации и вёрстки.
Тесты 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").
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 не имеет автоматической синхронизации с сетевыми запросами.
// Ожидание появления элемента с таймаутом
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 поддерживает тестирование сложных сценариев: мультитач-жесты, пуш-уведомления, 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-средах через xcodebuild с флагом test. Для параллельного запуска на нескольких симуляторах используется xcodebuild -testPlan с настройкой параллельного выполнения в схеме Xcode. GitHub Actions, Bitrise и Jenkins имеют встроенную поддержку XCUITest.
Для CI требуется настроить code signing, provisioning profiles и указать дестинейшн (симулятор или устройство). iOS-тесты на симуляторе не требуют сертификатов. Для реальных устройств необходима автоматическая подпись через Xcode Cloud или Fastlane.
# Запуск 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
XCUITest тесно связан с Accessibility API Apple, поскольку поиск элементов основан на accessibility-атрибутах. Accessibility-тестирование — это не только способ поиска элементов, но и проверка доступности приложения для людей с ограниченными возможностями. XCUITest может проверять accessibilityLabel, traits и hints.
VoiceOver — экранный диктор Apple для незрячих пользователей. XCUITest позволяет проверить: accessibilityLabel описан ли элемент понятным текстом, accessibilityTraits соответствует ли тип элемента (кнопка, заголовок, изображение), и accessibilityHint даёт ли подсказку о результате действия. Эти проверки обязательны для публикации в App Store, и XCUITest автоматизирует их в составе регрессионного прогона.
Начиная с Xcode 15, XCUITest поддерживает встроенную проверку Accessibility через XCTAttachment с типом accessibilityAudit. Тест автоматически сообщает об элементах с недостаточной контрастностью, неподписанных изображениях и некорректных traits. Это заменяет ручной Accessibility Inspector.
// 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)
}
XCUITest поддерживает измерение производительности UI через XCTOSSignpostMetric и XCUIApplication.metrics. Можно измерить время запуска приложения (launch time), скорость навигации, время отклика на жесты. Performance-тесты запускаются с измерением baseline и автоматически падают при превышении порога. Это позволяет предотвратить регрессии производительности до того, как они попадут к пользователям в релизной сборке.
Baseline — это эталонное время выполнения теста. Xcode запоминает baseline для каждого теста на конкретной модели устройства и версии iOS. Если новый запуск превышает baseline на заданный процент (по умолчанию 10%), тест считается упавшим. Для обновления baseline используется команда Edit Baseline в отчёте тестов. Важно пересчитывать baseline при обновлении версии iOS или смене модели устройства для CI-фермы.
Для отслеживания стабильности XCUITest-тестов используются флаги: continueAfterFailure (продолжать ли тест после первого падения) и тестовые планы Xcode с конфигурациями повторов. Рекомендуется настраивать автоматический перезапуск упавших тестов (retry) — до 3 попыток для флапающих тестов, связанных с таймингами анимаций или сетевыми задержками.
XCUITest поддерживает тестирование push-уведомлений и Deep Links через springboard и launchArguments. Для push-уведомлений используется XCUIApplication().launchArguments с параметром -UNUserNotificationCenter и отправка через XCTest. Deep Links тестируются через open URL с указанием кастомной схемы — XCUITest перехватывает системный диалог и проверяет, открылось ли приложение с правильным экраном. Для тестирования сценария ответа на уведомление используется XCUIApplication().springboard, который симулирует нажатие на баннер уведомления в центре уведомлений iOS. Эти сценарии критически важны для приложений с диплинками и push-кампаниями, где требуется проверить корректность обработки внешних вызовов.
Для детального профилирования производительности XCUITest интегрируется с Instruments. Во время теста можно запустить профилирование Time Profiler, Core Animation, или Leaks через XCTMetric. Результаты профилирования сохраняются в отчёте и доступны для анализа в Xcode. Это особенно полезно при оптимизации времени запуска приложения, навигации между экранами и производительности анимаций — типовых узких мест в iOS-приложениях.
Часто задаваемые вопросы
XCTest — это общий фреймворк для всех типов тестов Apple, включая юнит-тесты и performance-тесты. XCUITest — это надстройка над XCTest для UI-тестирования, которая добавляет классы XCUIApplication, XCUIElement и XCUIElementQuery для взаимодействия с интерфейсом.
Да, XCUITest поддерживает как Swift, так и Objective-C. Однако большинство примеров и документации Apple пишется на Swift. Objective-C-проекты могут использовать XCUITest без дополнительных настроек — фреймворк доступен через @import XCTest.
XCUITest использует Accessibility API Apple. Элементы находятся по accessibilityIdentifier, accessibilityLabel, типу (button, textField, staticText) или положению в иерархии. Чем точнее заданы Accessibility-атрибуты в коде приложения, тем стабильнее тесты.
Да, Xcode включает встроенный рекордер UI-тестов. При запуске теста в режиме записи Xcode фиксирует все взаимодействия с интерфейсом и генерирует Swift-код. Записанный код можно доработать: добавить проверки, вынести в Page Objects и параметризовать.
Для запуска на реальном устройстве необходимо: подключить устройство к Mac, добавить его в Apple Developer Program, настроить provisioning profile, подписать приложение development-сертификатом и выбрать устройство в качестве дестинейшн в xcodebuild.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также