Passer au contenu principal
chapterjs test fait tourner votre bot dans un Discord qui vit en mémoire : un serveur, quelques personnes, et rien à quoi se connecter. Pas de token, pas de serveur de test, rien de montré à personne. C’est ce que lance le script test de votre projet :
C’est tout : sans rien écrire, chaque commande, bouton, menu, formulaire, événement et tâche de votre projet est utilisé une fois, avec des valeurs ordinaires et des valeurs difficiles, et doit répondre sans lancer d’erreur. Viennent ensuite vos scénarios, quand vous en avez : des fichiers qui disent ce que le bot doit répondre.
Ce qu’un scénario peut faire est dans la référence ; les codes de sortie de la commande sont dans la référence du CLI.

Ce qui est vérifié tout seul

Chaque fichier de src/ est chargé, comme chapterjs dev le fait. Un fichier qui ne peut pas tourner arrête tout, avec sa ligne : rien n’est testé tant qu’il n’est pas corrigé. Puis, dans un serveur où le bot est admin, chaque cas sur un serveur neuf (un /ban essayé sur quelqu’un ne prive donc jamais le cas suivant de cette personne) :
  • Chaque commande est utilisée avec toutes ses options remplies, puis avec les obligatoires seulement, puis une fois par valeur difficile : un texte au plus long et en unicode, un nombre au plus bas, au plus haut et à zéro, chacun de ses choices, une personne qui a quitté le serveur, le bot lui-même, le propriétaire. Une commande qui ne fonctionne qu’en message privé y est utilisée ; une qui fonctionne aux deux endroits est utilisée aux deux. Quelqu’un qui a les permissions que la commande demande l’utilise.
  • Chaque bouton, menu et formulaire est utilisé avec ses data, puis une fois par valeur difficile de ces données : un texte vide, un : dedans, un nombre énorme. Un formulaire est aussi envoyé avec ses champs obligatoires seulement.
  • Chaque événement se produit une fois : un message, quelqu’un qui arrive ou qui part, une réaction, un nouveau salon… Un événement que le serveur de test ne sait pas encore provoquer est nommé avec ℹ, et son fichier est laissé tranquille.
  • Chaque commande de menu est utilisée sur un message ou une personne ordinaires, puis sur les cas difficiles : un message à sa longueur maximale en unicode, un message du propriétaire ou de quelqu’un qui est parti ; le bot, le propriétaire, qui l’utilise, quelqu’un qui est parti.
  • Chaque tâche tourne une fois, comme si son heure était venue.
  • La présence, quand elle a des fonctions : chacune s’exécute une fois.
Les fichiers qui passent tiennent sur une ligne à la fin de ces vérifications : ce qui a été vérifié dedans n’est pas listé, puisque rien n’y est à lire pour vous. Pendant qu’un fichier est vérifié, le terminal l’affiche avec la chose et le cas en cours (↻ Checking src/tickets/close.ts, puis → button close(), with userId = ""…), et l’efface une fois fini. Une vérification réussit quand le bot a répondu et que rien n’a lancé d’erreur. Elle a 5 secondes pour répondre, comme sur Discord (une commande plus longue est différée par le framework, ce qui compte), puis 30 secondes pour finir. Elle échoue quand une fonction a lancé une erreur, avec le fichier et la ligne, quand une commande a fini sans répondre, ou quand le temps est écoulé ; c’est seulement là qu’un fichier a ses propres lignes, avec la chose nommée :
Ce que vos fichiers impriment pendant qu’ils sont testés (un console.log dans un événement, par exemple) reste hors du rapport : une ligne qui dirait « online » s’y lirait comme le bot en ligne, et il ne l’est pas. Ce qui a été imprimé est montré sous une vérification qui a échoué, là où ça peut aider. Ce que le bot répond n’est pas jugé ici : c’est à ça que servent les scénarios.

Scénarios

Un scénario est un test que vous écrivez, dans un fichier *.test.ts n’importe où dans src/, avec scenario() de chapterjs/test. Le bot ne charge jamais ces fichiers ; chapterjs test les lance, chacun sur un serveur neuf avec des stores vides.
src/checks/pong.ts
src/checks/pong.test.ts
bot est votre bot dans son serveur de test. bot.use() utilise une commande comme une personne le ferait, avec ses options typées depuis le fichier : une personne pour une option user, un nombre pour une option integer, l’un des choices. bot.click() appuie sur un bouton, bot.select() choisit dans un menu, bot.submit() envoie un formulaire, bot.say() écrit un message, bot.join() et bot.leave() font venir et partir quelqu’un, bot.run() lance une tâche. Chacun se résout une fois que le bot en a fini. Ce qui revient dit ce que le bot a répondu : says(), isEphemeral(), hasButton(), opensForm(), updatesMessage()… Chaque vérification lance une phrase en clair quand elle échoue. Le rapport a une ligne par fichier de test, et ne nomme un scénario que quand il a échoué, avec la ligne de votre scénario :
Pour tout le reste, node:assert fonctionne comme dans n’importe quel test :
src/checks/strikes.ts
src/checks/strikes.test.ts
Un scénario échoue aussi quand une fonction du bot a lancé une erreur pendant qu’il tournait, même si chaque vérification est passée : une personne aurait vu « Something went wrong ». Une commande de menu s’utilise avec on : bot.use(quote, { on: message }), bot.use(avatar, { on: alice }) (voir Commandes de menu). Une fonction qui attend une réponse laisse bot.use() se résoudre pendant qu’elle attend : le bot.say(), bot.click() ou bot.react() suivant est ce qu’elle attend, et bot.endWaits() termine chaque attente comme si son temps était écoulé.

Le serveur de test

Il a un salon, #general, son propriétaire (bot.owner), le bot en admin (bot.me), et bot.someone : une personne sans droit particulier, qui fait tout quand personne n’est nommé. bot.member('alice') crée une personne la première fois que le nom est donné (avec des permissions ou des roles quand il lui en faut), bot.role() un rôle et bot.channel() un salon. Tout ce que fait le bot est gardé là où le scénario peut le lire : channel.messages et channel.last, member.banned, member.timedOut, member.roles, member.privateMessages, channel.threads, thread.archived… Et le serveur refuse ce que Discord refuserait : une seconde réponse à la même interaction, un membre qui n’est pas là, un salon supprimé, et, comme sur Discord, expulser, bannir, renommer ou donner un rôle au propriétaire ou à quelqu’un dont le rôle le plus haut est au-dessus de celui du bot (un rôle créé par le scénario va sous celui du bot, comme un nouveau rôle sur Discord). Un formulaire envoyé sans un champ obligatoire, ou une commande utilisée sans une option obligatoire, est refusé avant d’atteindre le bot, comme l’application Discord le ferait.

Ce qu’il ne fait pas encore

Le temps ne passe pas : un cooldown, ou une tâche qui tourne every tant de temps, ne se teste pas par l’horloge, et une attente ne se termine que quand le test y répond ou appelle bot.endWaits(). Le vocal n’est pas là : join() lève une erreur tout de suite, et ce qui vient après est nommé avec ℹ au lieu d’échouer. Ni les sondages, les événements planifiés et l’auto-modération : un événement que le serveur ne sait pas provoquer est nommé dans le rapport, et une requête pour quelque chose qu’il ne modélise pas répond comme Discord le fait pour ce qui n’existe pas, donc votre fonction voit la même erreur qu’en ligne.

Référence des tests

Tout ce qu’un scénario peut faire, et ce qu’une réponse peut vérifier.

chapterjs build

Vérifier les types et compiler le bot pour la production.