Exercice 2 / Étape 5 — Tests E2E avec Cypress¶
Tests de bout en bout des écrans du front-end, API mockée via
cy.intercept() (aucun appel au vrai back-end), en commençant par les
formulaires les plus simples comme demandé par la consigne.
Installation¶
Cypress n'était pas encore une dépendance du projet :
Config créée :
cypress.config.ts— E2E,baseUrl: 'http://localhost:4200'.cypress/support/e2e.ts/cypress/support/commands.ts— commande personnaliséecy.visitAuthenticated(url): seed un faux JWT danslocalStorageavant l'exécution des scripts de la page (optiononBeforeLoad), pour atteindre les routes protégées parauthGuardsans repasser par tout le flux/login.cypress/tsconfig.json— scope les types Cypress àcypress/**, séparé detsconfig.spec.json(Jest) pour éviter tout conflit de types entre les deux frameworks de test.
Specs écrites (du plus simple au plus complexe)¶
| Spec | Ce qui est mocké | Vérifie |
|---|---|---|
register.cy.ts |
POST /api/register → 201 |
soumission valide → redirection /login ; formulaire invalide → pas d'appel API |
login.cy.ts |
POST /api/login → 200 (texte brut) / 400 |
soumission valide → redirection /students ; identifiants refusés → message d'erreur affiché |
students-guard.cy.ts |
— | accès à /students sans session → redirection /login (authGuard) |
students-list.cy.ts |
GET /api/students → liste / liste vide |
rendu du tableau / état "No students yet." |
students-create.cy.ts |
POST /api/students → 201 |
soumission du formulaire → requête envoyée avec le bon corps, retour sur /students |
students-delete.cy.ts |
GET + DELETE /api/students/:id |
confirmation navigateur stubée (window:confirm), suppression déclenchée |
Bug détecté par ces tests (voir détail dans l'étape 4)¶
Le premier passage de login.cy.ts (cas d'identifiants refusés) a échoué :
le message "Invalid credentials" attendu à l'écran n'apparaissait jamais.
Root cause et correctif détaillés dans le doc de l'étape 4 —
LoginComponent ne parsait pas correctement le corps d'erreur HTTP
lorsque la requête est faite avec responseType: 'text'. C'est exactement
le genre de régression qu'un test E2E (contrairement à un simple curl)
est censé attraper : il exécute le vrai code du composant dans un vrai
navigateur, pas seulement la couche HTTP.
Exécution réelle dans cet environnement¶
Contrairement aux vérifications précédentes de ce projet (étapes 3 et 5 de
l'Exercice 1), Cypress a pu s'exécuter en mode headless dans cet
environnement WSL (npx cypress verify → OK, Electron headless
disponible) :
Spec Tests Passing Failing
login.cy.ts 2 2 -
register.cy.ts 2 2 -
students-create.cy.ts 1 1 -
students-delete.cy.ts 1 1 -
students-guard.cy.ts 1 1 -
students-list.cy.ts 2 2 -
──────────────────────────────────────────────────
All specs passed! 9 9 -
9/9 tests passent, sur les 6 écrans couverts par le plan de tests — tous les écrans listés à l'étape 2 sont couverts, avec succès.
Comment reproduire¶
cd front-end
npm install # installe aussi cypress (devDependency)
npm run start # terminal 1 — ng serve sur :4200 (nécessaire, Cypress vise cette URL)
# terminal 2
npx cypress run # exécution headless, résultats dans le terminal
# ou, pour piloter/déboguer visuellement :
npx cypress open
Aucun back-end réel n'est nécessaire : tous les appels /api/** sont
interceptés par cy.intercept().
Points de vigilance restants¶
- Pas de notion formelle de "taux de couverture E2E" outillée (Cypress n'a pas d'équivalent direct de JaCoCo/Istanbul pour ça) — la couverture est démontrée ici par la correspondance 1:1 entre les écrans du plan de tests (étape 2) et les specs écrites : les 6 écrans/parcours prévus ont chacun au moins un test, tous passent.
students-create.cy.ts/students-delete.cy.tsne couvrent qu'un seul cas nominal chacun — les cas d'erreur (email dupliqué, suppression en échec) ne sont pas testés en E2E, déjà couverts côté Jest (étape 4).