XCUITest est un framework Apple pour les tests UI des applications iOS, iPadOS et macOS, intégré directement dans XCTest et Xcode. Il permet de simuler les actions de l’utilisateur : tap, saisie de texte, balayages, défilement et gestes — avec un accès à l’état interne des éléments de l’interface. Selon Apple Developer Documentation, 2025, XCUIApplication est le point d’entrée pour tous les tests UI et donne accès à la hiérarchie des éléments de l’écran.
Points clés
XCUITest est un framework de test UI publié par Apple dans Xcode 7 (2015). Il a remplacé UI Automation (UIA) et est devenu l’outil standard pour les tests d’interface automatisés sur les plateformes Apple. XCUITest est entièrement intégré à XCTest — le framework de test unifié d’Apple.
Contrairement aux tests unitaires qui vérifient la logique au niveau des classes et des méthodes, XCUITest teste l’interface utilisateur par simulation d’actions. Les tests s’exécutent dans un processus séparé de l’application et interagissent avec elle via l’API d’accessibilité — cela garantit l’isolation et la fiabilité.
XCUITest ne nécessite pas l’installation de serveurs tiers (contrairement à Appium) ni de bibliothèques supplémentaires pour l’interaction avec l’appareil. Tout le nécessaire est déjà inclus dans Xcode. Cela garantit la meilleure compatibilité avec les nouvelles versions d’iOS et un accès instantané aux nouveaux gestes et contrôles.
L’architecture de XCUITest repose sur deux classes clés : XCUIApplication — l’application testée lancée, et XCUIElement — l’élément d’interface. L’exécuteur de tests XCTest gère le cycle de vie des tests : setUp, méthodes de test, tearDown. XCUITest s’exécute comme un processus séparé qui contrôle l’application via le pont d’accessibilité.
Chaque élément UI est représenté par un objet XCUIElement contenant des méthodes pour interroger l’état (exists, isHittable, label, value) et les actions (tap, pressForDuration, swipeUp, typeText). Les éléments sont organisés en hiérarchie via des chaînes de requête : app.buttons[].staticTexts[].tables[]. Cela permet de trouver flexiblement n’importe quel élément à l’écran.
XCUITest utilise les attributs d’accessibilité pour identifier les éléments : accessibilityIdentifier — un identifiant programmatique, et accessibilityLabel — une description pour VoiceOver. Il est recommandé de définir accessibilityIdentifier dans le code de l’application — cela rend les tests stables indépendamment de la localisation et de la mise en page.
Les tests XCUITest s’écrivent en Swift en utilisant la syntaxe XCTest. Chaque classe de test hérite de XCTestCase et contient des méthodes commençant par test. Dans la méthode setUp, l’application est lancée avec la configuration nécessaire, et dans tearDown, le nettoyage et la fin de session sont effectués.
Un test typique : trouver un élément → effectuer une action → vérifier le résultat. La recherche d’éléments se fait via des requêtes enfants XCUIElementQuery : app.buttons["loginButton"], app.textFields["email"]. Actions : .tap(), .typeText("text"), .swipeUp(). Vérifications : XCTAssertTrue(element.exists) ou 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 prend en charge les attentes explicites via XCTWaiter et les prédicats NSPredicate. Par exemple, attendre l’apparition d’un élément dans les 5 secondes : XCTWaiter().wait(for: [expectation], timeout: 5). Contrairement à Detox, XCUITest n’a pas de synchronisation automatique avec les requêtes réseau.
// Attente de l’apparition de l’élément avec délai d’expiration
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 prend en charge les tests de scénarios complexes : gestes multitouch, notifications push, Deep Links, SFSafariViewController et interactions inter-applications. Les intents Siri peuvent également être testés via XCUITest avec la simulation Siri Remote.
XCUITest prend en charge tous les gestes courants : tap, doubleTap, pressForDuration, swipeUp/Down/Left/Right, pinch, rotate, twoFingerTap. Pour les scénarios complexes, XCUIGesture est utilisé avec des coordonnées et une durée personnalisées. Cela permet de tester des gestes personnalisés comme le dessin ou le glisser-déposer.
À partir de Xcode 12, XCUITest prend en charge l’interception des requêtes réseau via XCTestExpectation et URLProtocol. Cela permet de tester l’application en mode hors ligne ou avec des réponses serveur simulées sans modifier le code de l’application.
XCUITest s’exécute dans les environnements CI via xcodebuild avec le flag test. Pour l’exécution parallèle sur plusieurs simulateurs, on utilise xcodebuild -testPlan avec une configuration d’exécution parallèle dans le schéma Xcode. GitHub Actions, Bitrise et Jenkins ont un support intégré pour XCUITest.
Pour le CI, il faut configurer la signature de code, les profils de provisionnement et spécifier la destination (simulateur ou appareil). Les tests iOS sur simulateur ne nécessitent pas de certificats. Pour les appareils réels, une signature automatique est nécessaire via Xcode Cloud ou Fastlane.
# Exécution de XCUITest sur simulateur via 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 est étroitement lié à l’API d’accessibilité d’Apple, car la recherche d’éléments est basée sur les attributs d’accessibilité. Le test d’accessibilité n’est pas seulement un moyen de trouver des éléments, mais aussi de vérifier l’accessibilité de l’application pour les personnes handicapées. XCUITest peut vérifier accessibilityLabel, traits et hints.
VoiceOver est le lecteur d’écran d’Apple pour les utilisateurs malvoyants. XCUITest permet de vérifier : accessibilityLabel — si l’élément est décrit avec un texte clair, accessibilityTraits — si le type d’élément correspond (bouton, titre, image), et accessibilityHint — s’il fournit une indication sur le résultat de l’action. Ces vérifications sont obligatoires pour la publication sur l’App Store, et XCUITest les automatise dans le cadre des exécutions de régression.
À partir de Xcode 15, XCUITest prend en charge la vérification intégrée de l’accessibilité via XCTAttachment avec le type accessibilityAudit. Le test signale automatiquement les éléments avec un contraste insuffisant, les images non étiquetées et les traits incorrects. Cela remplace l’inspecteur d’accessibilité manuel.
// Audit d’accessibilité dans XCUITest
func testAccessibilityAudit() {
let app = XCUIApplication()
app.launch()
let audit = XCTAttachment(accessibilityAudit: app)
add(audit)
// Vérification d’un élément spécifique
let button = app.buttons["submitButton"]
XCTAssertTrue(button.label.count > 0)
XCTAssertTrue(button.isAccessibilityElement)
}
XCUITest prend en charge la mesure des performances UI via XCTOSSignpostMetric et XCUIApplication.metrics. On peut mesurer le temps de démarrage de l’application, la vitesse de navigation et le temps de réponse aux gestes. Les tests de performance sont exécutés avec une mesure de référence et échouent automatiquement lorsque le seuil est dépassé. Cela permet d’éviter les régressions de performance avant qu’elles n’atteignent les utilisateurs dans une version de publication.
La référence (baseline) est le temps d’exécution de référence d’un test. Xcode mémorise la référence pour chaque test sur un modèle d’appareil et une version iOS spécifiques. Si une nouvelle exécution dépasse la référence d’un pourcentage défini (par défaut 10%), le test est considéré comme échoué. Pour mettre à jour la référence, utilisez la commande Edit Baseline dans le rapport de test. Il est important de recalculer la référence lors de la mise à jour de la version iOS ou du changement de modèle d’appareil pour la ferme CI.
Pour surveiller la stabilité des tests XCUITest, des flags sont utilisés : continueAfterFailure (continuer le test après le premier échec) et les plans de test Xcode avec des configurations de réessai. Il est recommandé de configurer le redémarrage automatique des tests échoués (retry) — jusqu’à 3 tentatives pour les tests instables liés au timing des animations ou aux délais réseau.
XCUITest prend en charge le test des notifications push et des Deep Links via springboard et launchArguments. Pour les notifications push, on utilise XCUIApplication().launchArguments avec le paramètre -UNUserNotificationCenter et l’envoi via XCTest. Les Deep Links sont testés via open URL avec un schéma personnalisé — XCUITest intercepte la boîte de dialogue système et vérifie si l’application s’est ouverte avec le bon écran. Pour tester le scénario de réponse à une notification, on utilise XCUIApplication().springboard, qui simule le tap sur la bannière de notification dans le centre de notifications iOS. Ces scénarios sont critiques pour les applications avec des deep links et des campagnes push, où il est nécessaire de vérifier le traitement correct des appels externes.
Pour le profilage détaillé des performances, XCUITest s’intègre à Instruments. Pendant le test, le profilage de Time Profiler, Core Animation ou Leaks peut être lancé via XCTMetric. Les résultats du profilage sont enregistrés dans le rapport et disponibles pour analyse dans Xcode. Ceci est particulièrement utile pour optimiser le temps de démarrage de l’application, la navigation entre les écrans et les performances des animations — des goulots d’étranglement typiques dans les applications iOS.
Questions fréquentes
XCTest est le framework général pour tous les types de tests Apple, y compris les tests unitaires et les tests de performance. XCUITest est une extension au-dessus de XCTest pour les tests UI qui ajoute les classes XCUIApplication, XCUIElement et XCUIElementQuery pour interagir avec l’interface.
Oui, XCUITest prend en charge Swift et Objective-C. Cependant, la plupart des exemples et de la documentation Apple sont écrits en Swift. Les projets Objective-C peuvent utiliser XCUITest sans configuration supplémentaire — le framework est disponible via @import XCTest.
XCUITest utilise l’API d’accessibilité d’Apple. Les éléments sont trouvés par accessibilityIdentifier, accessibilityLabel, type (button, textField, staticText) ou position dans la hiérarchie. Plus les attributs d’accessibilité sont précis dans le code de l’application, plus les tests sont stables.
Oui, Xcode inclut un enregistreur intégré de tests UI. Lors de l’exécution d’un test en mode enregistrement, Xcode capture toutes les interactions avec l’interface et génère du code Swift. Le code enregistré peut être affiné : ajouter des vérifications, extraire dans des Page Objects et paramétrer.
Pour exécuter sur un appareil réel, il faut : connecter l’appareil à un Mac, l’ajouter au Apple Developer Program, configurer un profil de provisionnement, signer l’application avec un certificat de développement et sélectionner l’appareil comme destination dans xcodebuild.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi