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). Елементите са организирани в йерархия чрез вериги за запитване: 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 поддържа тестване на сложни сценарии: мултитъч жестове, push известия, Deep Links, SFSafariViewController и междуприложно взаимодействие. Siri интенциите също могат да бъдат тествани чрез XCUITest с използване на симулация на Siri Remote.
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, тъй като търсенето на елементи се основава на атрибутите за достъпност. Тестване на достъпността — не е само метод за намиране на елементи, но и проверка на достъпността на приложението за хора с увреждания. XCUITest може да проверява accessibilityLabel, traits и hints.
VoiceOver — екранният четец на Apple за незрящи потребители. XCUITest позволява проверка: accessibilityLabel — дали елементът е описан с разбираем текст, accessibilityTraits — дали типът на елемента съответства (бутон, заглавие, изображение), и accessibilityHint — дали дава подсказка за резултата от действието. Тези проверки са задължителни за публикуване в App Store и XCUITest ги автоматизира в рамките на регресионното изпълнение.
От Xcode 15, XCUITest поддържа вградена проверка на Accessibility чрез XCTAttachment с тип accessibilityAudit. Тестът автоматично докладва за елементи с недостатъчен контраст, неподписани изображения и неправилни traits. Това заменя ръчния Accessibility Inspector.
// Одит на достъпността в 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), скоростта на навигация, времето за отговор на жестове. Тестовете за производителност се изпълняват с измерване на 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, включително единични тестове и тестове за производителност. 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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също