Pourquoi les tests E2E sont-ils le « mode dieu » pour le développeur iOS ?
\n\nImaginez : vous avez écrit un code Swift parfait, tout compile, les tests unitaires sont verts. Vous publiez une version — et une heure plus tard, les bugs arrivent : le bouton « Acheter » ne répond pas sur iPhone 14 Pro, et sur iPad Mini, l'écran de connexion ressemble à une peinture abstraite. Cela vous dit quelque chose ? C'est là qu'intervient le test E2E Swift — le seul moyen d'être certain que votre application fonctionne comme une horloge entre les mains d'un utilisateur réel.
\n\nLes tests End-to-End (E2E) simulent un scénario utilisateur complet : du lancement de l'application jusqu'à la réalisation de l'action cible (achat, inscription, envoi de formulaire). Dans cet article, nous verrons comment configurer XCUITest Swift pour que vos tests ne tombent pas pour des broutilles et que votre pipeline CI/CD ne devienne pas un enfer.
\n\nCe que vous allez apprendre :
\n- \n
- Comment écrire des tests UI stables avec XCUITest \n
- Page Object Model pour Swift — exemple concret \n
- Gestion des opérations asynchrones et des attentes \n
- Intégration des tests E2E dans CI/CD (GitHub Actions + Fastlane) \n
- Top 3 des erreurs de débutants et comment les éviter \n
Boîte à outils : de quoi avons-nous besoin
\n\nPour l'automatisation des tests Swift, nous utilisons trois piliers :
\n- \n
- XCUITest — le framework d'Apple, intégré à XCTest. Permet d'émuler des gestes, de vérifier les états des éléments UI. \n
- Xcode Test Plan — pour configurer les schémas de test (différentes langues, orientations, données). \n
- Fastlane + GitHub Actions — pour exécuter les tests sur CI. \n
La syntaxe de base de XCUITest est simple : vous accédez à l'application via XCUIApplication(), recherchez des éléments avec buttons["Login"] ou textFields["email"] et émulez des actions.
Écrire notre premier test E2E : scénario de connexion
\n\nSupposons que nous ayons un écran de connexion avec les champs Email, Mot de passe et un bouton « Se connecter ». Objectif : vérifier qu'avec des données correctes, l'utilisateur accède à l'écran principal.
\n\nimport XCTest\n\nclass LoginE2ETests: XCTestCase {\n \n let app = XCUIApplication()\n \n override func setUpWithError() throws {\n continueAfterFailure = false\n app.launch()\n }\n \n func testSuccessfulLogin() throws {\n // 1. Trouver les éléments\n let emailField = app.textFields["emailTextField"]\n let passwordField = app.secureTextFields["passwordTextField"]\n let loginButton = app.buttons["signInButton"]\n \n // 2. Actions de l'utilisateur\n emailField.tap()\n emailField.typeText("user@example.com")\n \n passwordField.tap()\n passwordField.typeText("ValidPassword123")\n \n loginButton.tap()\n \n // 3. Vérifier le résultat\n let dashboard = app.staticTexts["dashboardTitle"]\n XCTAssertTrue(dashboard.waitForExistence(timeout: 5))\n }\n}\n\nPoint important : utilisez waitForExistence(timeout:) — sans cela, le test peut échouer si une animation ou une requête réseau prend du temps. C'est la base du test E2E Swift.
Pourquoi ce code pourrait-il échouer ?
\n- \n
- Le champ de saisie peut ne pas être le premier responder — ajoutez
.tap()avanttypeText. \n - Le bouton peut être masqué par le clavier — utilisez
app.keyboards.buttons["Return"].tap(). \n - Les étiquettes de texte peuvent différer selon la localisation — utilisez toujours Accessibility Identifier. \n
Page Object Model (POM) pour Swift : rendre les tests propres
\n\nLorsque l'application grandit, les tests deviennent un fouillis. La solution — le Page Object Model. Nous créons des classes séparées pour chaque écran, encapsulant la logique de recherche d'éléments et les actions.
\n\nExemple pour l'écran de connexion :
\n\n// Lo