XCUITest è un framework Apple per il test UI di applicazioni iOS, iPadOS e macOS, integrato direttamente in XCTest e Xcode. Consente di simulare le azioni dell’utente: tocchi, inserimento di testo, scorrimenti, swipe e gesti — con accesso allo stato interno degli elementi dell’interfaccia. Secondo Apple Developer Documentation, 2025, XCUIApplication è il punto di ingresso per tutti i test UI e fornisce accesso alla gerarchia degli elementi dello schermo.
Punti chiave
XCUITest è un framework di test UI rilasciato da Apple in Xcode 7 (2015). Ha sostituito UI Automation (UIA) ed è diventato lo strumento standard per il test automatizzato dell’interfaccia sulle piattaforme Apple. XCUITest è completamente integrato in XCTest — il framework di test unificato di Apple.
A differenza dei test unitari, che verificano la logica a livello di classi e metodi, XCUITest testa l’interfaccia utente attraverso la simulazione di azioni. I test vengono eseguiti in un processo separato dall’applicazione e interagiscono con essa tramite l’API di accessibilità — questo garantisce isolamento e affidabilità.
XCUITest non richiede l’installazione di server di terze parti (a differenza di Appium) o librerie aggiuntive per l’interazione con il dispositivo. Tutto il necessario è già incluso in Xcode. Questo garantisce la migliore compatibilità con le nuove versioni di iOS e l’accesso immediato a nuovi gesti e controlli.
L’architettura di XCUITest si basa su due classi chiave: XCUIApplication — l’applicazione in test avviata, e XCUIElement — l’elemento dell’interfaccia. Il test runner XCTest gestisce il ciclo di vita dei test: setUp, metodi di test, tearDown. XCUITest viene eseguito come un processo separato che controlla l’applicazione attraverso il ponte di accessibilità.
Ogni elemento UI è rappresentato da un oggetto XCUIElement che contiene metodi per interrogare lo stato (exists, isHittable, label, value) e le azioni (tap, pressForDuration, swipeUp, typeText). Gli elementi sono organizzati in una gerarchia attraverso catene di query: app.buttons[].staticTexts[].tables[]. Ciò consente di trovare qualsiasi elemento sullo schermo in modo flessibile.
XCUITest utilizza gli attributi di accessibilità per identificare gli elementi: accessibilityIdentifier — un identificatore programmatico, e accessibilityLabel — una descrizione per VoiceOver. Si consiglia di impostare accessibilityIdentifier nel codice dell’applicazione — questo rende i test stabili indipendentemente dalla localizzazione e dal layout.
I test XCUITest sono scritti in Swift utilizzando la sintassi XCTest. Ogni classe di test eredita da XCTestCase e contiene metodi che iniziano con test. Nel metodo setUp, l’applicazione viene avviata con la configurazione necessaria, e in tearDown vengono eseguiti la pulizia e la chiusura della sessione.
Un test tipico: trovare un elemento → eseguire un’azione → verificare il risultato. La ricerca degli elementi avviene tramite query figlie di XCUIElementQuery: app.buttons["loginButton"], app.textFields["email"]. Azioni: .tap(), .typeText("text"), .swipeUp(). Verifiche: XCTAssertTrue(element.exists) o 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 supporta attese esplicite tramite XCTWaiter e predicati NSPredicate. Ad esempio, attendere la comparsa di un elemento entro 5 secondi: XCTWaiter().wait(for: [expectation], timeout: 5). A differenza di Detox, XCUITest non ha sincronizzazione automatica con le richieste di rete.
// Attesa della comparsa dell’elemento con timeout
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 supporta il test di scenari complessi: gesti multi-touch, notifiche push, Deep Links, SFSafariViewController e interazione tra applicazioni. Gli intent Siri possono anche essere testati tramite XCUITest con la simulazione di Siri Remote.
XCUITest supporta tutti i gesti più comuni: tap, doubleTap, pressForDuration, swipeUp/Down/Left/Right, pinch, rotate, twoFingerTap. Per scenari complessi, viene utilizzato XCUIGesture con coordinate e durata personalizzate. Ciò consente di testare gesti personalizzati come il disegno o il drag-and-drop.
A partire da Xcode 12, XCUITest supporta l’intercettazione delle richieste di rete tramite XCTestExpectation e URLProtocol. Ciò consente di testare l’applicazione in modalità offline o con risposte del server simulate senza modificare il codice dell’applicazione.
XCUITest viene eseguito in ambienti CI tramite xcodebuild con il flag test. Per l’esecuzione parallela su più simulatori, si utilizza xcodebuild -testPlan con configurazione di esecuzione parallela nello schema Xcode. GitHub Actions, Bitrise e Jenkins hanno supporto integrato per XCUITest.
Per CI, è necessario configurare il code signing, i provisioning profile e specificare la destinazione (simulatore o dispositivo). I test iOS sul simulatore non richiedono certificati. Per i dispositivi reali, è necessaria la firma automatica tramite Xcode Cloud o Fastlane.
# Esecuzione di XCUITest sul simulatore tramite 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 è strettamente legato all’API di accessibilità di Apple, poiché la ricerca degli elementi si basa sugli attributi di accessibilità. Il test di accessibilità non è solo un modo per trovare elementi, ma anche per verificare l’accessibilità dell’applicazione per le persone con disabilità. XCUITest può verificare accessibilityLabel, traits e hints.
VoiceOver è il lettore dello schermo di Apple per utenti ipovedenti. XCUITest consente di verificare: accessibilityLabel — se l’elemento è descritto con testo chiaro, accessibilityTraits — se il tipo di elemento corrisponde (pulsante, intestazione, immagine), e accessibilityHint — se fornisce un suggerimento sul risultato dell’azione. Queste verifiche sono obbligatorie per la pubblicazione sull’App Store e XCUITest le automatizza come parte delle esecuzioni di regressione.
A partire da Xcode 15, XCUITest supporta la verifica integrata dell’accessibilità tramite XCTAttachment con il tipo accessibilityAudit. Il test segnala automaticamente gli elementi con contrasto insufficiente, immagini senza etichetta e traits errati. Ciò sostituisce l’ispettore di accessibilità manuale.
// Audit di accessibilità in XCUITest
func testAccessibilityAudit() {
let app = XCUIApplication()
app.launch()
let audit = XCTAttachment(accessibilityAudit: app)
add(audit)
// Verifica di un elemento specifico
let button = app.buttons["submitButton"]
XCTAssertTrue(button.label.count > 0)
XCTAssertTrue(button.isAccessibilityElement)
}
XCUITest supporta la misurazione delle performance UI tramite XCTOSSignpostMetric e XCUIApplication.metrics. È possibile misurare il tempo di avvio dell’applicazione, la velocità di navigazione e il tempo di risposta ai gesti. I test di performance vengono eseguiti con misurazione della baseline e falliscono automaticamente quando viene superata la soglia. Ciò aiuta a prevenire regressioni di performance prima che raggiungano gli utenti in una versione di rilascio.
La baseline è il tempo di esecuzione di riferimento di un test. Xcode ricorda la baseline per ogni test su un modello di dispositivo e una versione iOS specifici. Se una nuova esecuzione supera la baseline di una percentuale definita (default 10%), il test è considerato fallito. Per aggiornare la baseline, si utilizza il comando Edit Baseline nel rapporto di test. È importante ricalcolare la baseline quando si aggiorna la versione di iOS o si cambia il modello di dispositivo per la farm CI.
Per monitorare la stabilità dei test XCUITest, vengono utilizzati flag: continueAfterFailure (se continuare il test dopo il primo fallimento) e piani di test Xcode con configurazioni di ripetizione. Si consiglia di configurare il riavvio automatico dei test falliti (retry) — fino a 3 tentativi per test instabili legati al tempismo delle animazioni o ai ritardi di rete.
XCUITest supporta il test di notifiche push e Deep Links tramite springboard e launchArguments. Per le notifiche push, si utilizza XCUIApplication().launchArguments con il parametro -UNUserNotificationCenter e l’invio tramite XCTest. I Deep Links vengono testati tramite open URL con uno schema personalizzato — XCUITest intercetta il dialogo di sistema e verifica se l’applicazione si è aperta con lo schermo corretto. Per testare lo scenario di risposta alla notifica, si utilizza XCUIApplication().springboard, che simula il tocco sul banner di notifica nel centro notifiche iOS. Questi scenari sono critici per le applicazioni con deep link e campagne push, dove è necessario verificare la corretta gestione delle chiamate esterne.
Per la profilazione dettagliata delle performance, XCUITest si integra con Instruments. Durante il test, è possibile avviare la profilazione di Time Profiler, Core Animation o Leaks tramite XCTMetric. I risultati della profilazione vengono salvati nel rapporto e sono disponibili per l’analisi in Xcode. Ciò è particolarmente utile per ottimizzare il tempo di avvio dell’applicazione, la navigazione tra schermate e le performance delle animazioni — colli di bottiglia tipici nelle applicazioni iOS.
Domande frequenti
XCTest è il framework generale per tutti i tipi di test Apple, inclusi i test unitari e i test di performance. XCUITest è un’estensione sopra XCTest per il test UI che aggiunge le classi XCUIApplication, XCUIElement e XCUIElementQuery per interagire con l’interfaccia.
Sì, XCUITest supporta sia Swift che Objective-C. Tuttavia, la maggior parte degli esempi e della documentazione Apple sono scritti in Swift. I progetti Objective-C possono utilizzare XCUITest senza configurazione aggiuntiva — il framework è disponibile tramite @import XCTest.
XCUITest utilizza l’API di accessibilità di Apple. Gli elementi vengono trovati per accessibilityIdentifier, accessibilityLabel, tipo (button, textField, staticText) o posizione nella gerarchia. Più precisi sono gli attributi di accessibilità nel codice dell’applicazione, più stabili saranno i test.
Sì, Xcode include un registratore integrato di test UI. Quando si esegue un test in modalità registrazione, Xcode cattura tutte le interazioni con l’interfaccia e genera codice Swift. Il codice registrato può essere perfezionato: aggiungere verifiche, estrarre in Page Objects e parametrizzare.
Per eseguire su un dispositivo reale è necessario: collegare il dispositivo a un Mac, aggiungerlo all’Apple Developer Program, configurare un provisioning profile, firmare l’applicazione con un certificato di sviluppo e selezionare il dispositivo come destinazione in xcodebuild.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche