Les tests de vérification d’e-mail sont la partie d’un parcours d’inscription que la plupart des équipes répètent une fois, sur le chemin idéal, puis déclarent terminée. Les défaillances intéressantes sont ailleurs : un lien ouvert deux fois, un lien ouvert dans un autre navigateur, un code qui arrive après que l’utilisateur a déjà été vérifié, un message qui n’arrive jamais du tout. Cet article passe en revue les états qu’un parcours de vérification possède réellement et les cas qui valent la peine d’être couverts dans chacun d’eux.
Les états par lesquels passe un parcours de vérification
Avant d’écrire un test, écrivez les états. Un parcours décrit comme « vérifié » ou « non vérifié » dissimule au moins quatre situations distinctes, et chacune a son propre comportement correct.
| État | Ce que le système croit | Ce que l’utilisateur peut faire |
|---|---|---|
| Non vérifié, aucun envoi | Le compte existe mais n’est pas prouvé | Demander un autre message |
| Non vérifié, message en transit | Un jeton existe et a une durée de vie | Attendre, ou redemander |
| Vérifié | L’adresse a été prouvée par un jeton valide | Utiliser le compte normalement |
| Changement en attente | Une nouvelle adresse est proposée, l’ancienne encore valide | Confirmer ou annuler |
La plupart des défauts vivent dans les transitions, pas dans les états. Demandez-vous ce qui se passe quand un utilisateur demande un second message alors que le premier est encore en transit, ou confirme la nouvelle adresse alors qu’il est toujours connecté avec l’ancienne.
Que casse-t-on quand un lien de confirmation est ouvert deux fois ?
Rien ne devrait casser, et c’est exactement pourquoi cela vaut la peine d’être testé. Un lien de confirmation est livré par un canal que l’utilisateur ne contrôle pas entièrement : les clients de messagerie prévisualisent les liens, les analyseurs de sécurité les suivent, et les utilisateurs cliquent une seconde fois par impatience.
Le comportement souhaité est que la première utilisation valide consomme le parcours et que chaque utilisation ultérieure produise un résultat clair et inoffensif — une page « déjà vérifié », ou une invitation à se connecter — plutôt qu’une erreur que l’utilisateur ne peut pas interpréter. Ce que vous ne voulez pas, c’est un second événement de vérification qui réinitialise un mot de passe, réémet une session, ou échoue avec un message suggérant que le compte est cassé.
Il existe un cas connexe qui prend les équipes au dépourvu : deux comptes, une seule adresse. Si votre produit autorise la même adresse sur deux comptes, un unique message de confirmation ne doit pas pouvoir vérifier les deux. Testez-le délibérément.
Tester les chemins de changement d’e-mail et de réinitialisation
Changer une adresse et réinitialiser un mot de passe réutilisent la même machinerie avec une conséquence différente, et c’est là qu’une implémentation partagée commence à fuir.
Quand un utilisateur change d’adresse, les deux adresses existent pendant un moment. L’ancienne devrait encore pouvoir récupérer le compte, et la nouvelle ne devrait prendre effet qu’une fois prouvée. Quand un utilisateur réinitialise un mot de passe, la confirmation ne devrait pas servir aussi de vérification, et inversement. Tester ces chemins revient à vérifier qu’un jeton émis pour un usage est refusé par l’autre, ce qui est une petite assertion qui prévient une grande classe de bugs.
Une fixture utile pour ce travail est une boîte que nul autre cas n’utilise, afin que le message que vous ouvrez soit certainement celui que le parcours vient d’envoyer. L’outil de courrier temporaire crée exactement ce genre d’adresse, et l’article sur les tests d’OTP dans les suites de bout en bout traite de l’extraction du code une fois qu’il est arrivé.
Que devrait-il se passer quand le courrier n’arrive jamais ?
C’est le chemin que les équipes sautent, et c’est celui que les utilisateurs rencontrent le plus souvent, car le courrier échoue pour des raisons que personne ne contrôle : une faute de frappe dans l’adresse, un fournisseur qui écarte silencieusement le message, un expéditeur brièvement limité en débit.
Le parcours devrait traiter la non-arrivée comme un résultat normal. L’utilisateur devrait pouvoir demander un autre message sans attendre un temps déraisonnable, l’interface devrait dire clairement que le message peut prendre un moment, et le compte ne devrait pas être laissé dans un état où l’utilisateur ne peut pas redemander parce qu’une requête est « déjà en attente ». Il ne s’agit ici d’aucun nombre précis de secondes ni de tentatives ; le point est que la conception ait une réponse, quelle qu’elle soit.
Lire un code depuis une boîte éphémère
Quand un parcours envoie un code court plutôt qu’un lien, le test a besoin du code contenu dans le message. Le lire depuis une boîte créée pour l’exécution garde l’assertion étroite : le message que vous trouvez ne peut appartenir qu’au cas que vous exécutez, ce qui élimine la cause la plus courante d’un test qui réussit pour la mauvaise raison.
Cela tient aussi les vraies boîtes complètement à l’écart du test. L’adresse d’un collègue ne devrait jamais être la destinataire de votre suite de non-régression, à la fois parce qu’il recevra le trafic et parce que vos assertions dépendraient alors d’une boîte que vous ne contrôlez pas.
Pour les développeurs : jetons, idempotence et chemin malheureux
Modélisez le jeton, pas seulement le formulaire. Trois propriétés méritent une couverture explicite.
L’usage unique est la première. Un jeton devrait être consommable une fois, et la seconde tentative devrait aboutir à un résultat bénin plutôt qu’à une erreur serveur. Lorsque la transition modifie quelque chose de conséquent, rendez l’opération idempotente afin qu’une répétition produise le même état final plutôt qu’un second effet.
L’expiration est la deuxième. Les jetons expirés devraient être distinguables des jetons invalides, dans vos journaux comme du point de vue de l’utilisateur, car les remèdes diffèrent : un jeton expiré signifie qu’il faut recommencer, un jeton invalide peut signifier que le mauvais lien a été copié. Ce qu’un jeton expiré ne doit pas faire, c’est laisser le compte dans un état à moitié modifié.
La concurrence est la troisième. Deux clics arrivant ensemble, ou un lien ouvert dans deux onglets, ne devraient pas pouvoir vérifier le même parcours deux fois. C’est une propriété de la couche de données, pas du bouton, donc testez-la en émettant les deux requêtes plutôt qu’en cliquant deux fois lentement.
Enfin, gardez la frontière claire dans vos fixtures et dans vos notes : ces adresses existent pour recevoir du courrier de test un moment, ce ne sont pas de vraies identités, et aucune fixture ne devrait laisser entendre le contraire.
Étapes suivantes
Prenez le parcours de vérification que vous avez livré le plus récemment et parcourez le tableau d’états ci-dessus en marquant les transitions que vous avez réellement testées. Exécutez ensuite celles que vous n’avez pas testées, en utilisant une adresse créée à neuf pour chaque cas depuis la page de courrier temporaire. Si vous préparez un lancement plus large, la liste de contrôle des tests d’e-mails transactionnels couvre le courrier environnant qu’un compte vérifié commencera à recevoir.