TP - Tests unitaires avec Alsatian
Alsatian est un outil de test pour les projets TypeScript. Il permet d’écrire des tests, de les exécuter et de récupérer les résultats sous une forme synthétique. Plus d’informations sur Alsatian ici.
1. Prise en main d’Alsatian avec le projet "Math"
1.1. Récupération du projet "Math"
-
Dans le répertoire de votre choix, clonez avec
git
le projet Math disponible à la page Gitlab suivante : https://gitlab.univ-nantes.fr/gl/developpement/math. -
Regardons le contenu du projet :
-
Le répertoire
src
contient le code TypeScript du projet, -
Le fichier
tsconfig.json
est présent comme d’habitude, mais avec quelques différences :-
La ligne
"outDir": "build"
indique que tout le code JavaScript compilé ira dans un unique répertoirebuild
, -
La ligne
"experimentalDecorators": true
est requise pour utiliser Alsatian, -
La ligne
"exclude": [ "node_modules" ]
indique à TypeScript de ne pas tenter de compiler les fichiers du répertoirenode_modules
, car ils contiendront les librairies externes déjà compilées (notamment Alsatian).
-
-
Enfin, le fichier
.gitignore
indique à git d’ignorer le répertoirebuild
car nous ne voulons pas commiter les fichiers compilés.
-
Pour l’instant, ce projet contient juste quelques fonctions TypeScript. Voyons comment ajouter et utiliser l’outil de test Altasian.
1.2. Installation d’Altasian
Pour utiliser Alsatian, il est nécessaire que votre projet de code TypeScript possède une dépendance envers l’outil Alsatian.
Pour cela, on va créer un fichier nommé package.json
permettant d’indiquer que nous avons besoin d’Alsatian, puis nous allons utiliser un outil appelé npm
qui va lire le fichier package.json
et ira télécharger Alsatian automatiquement.
-
Créez un fichier
package.json
à la racine de votre projet, et contenant les lignes suivantes :{ "scripts": { "test": "alsatian ./build/tests/*.js" }, "devDependencies": { "alsatian": "^3.2.1" } }
-
Dans un terminal, lancez la commande
npm install
.
Voilà, Alsatian est désormais installé dans votre projet, vous allez pouvoir ajouter et exécuter des tests !
1.3. Ajout et exécution de quelques tests
1.3.1. Ajout de tests
Nous allons maintenant créer et exécuter un premier fichier contenant des tests pour la fonction fibonacci
fournie par le projet Math.
-
Dans le projet Math, créez un répertoire
tests
. Attention à bien nommer ce répertoire (ne l’appelez pastest
) et à bien le placer à la racine, sinon vos tests ne s’executeront pas ! -
Dans le répertoire
tests
, créez un nouveau fichier appelémath-tests.ts
, et mettez y le contenu suivant :import { Expect, Test } from "alsatian"; import { fibonacci } from "../src/math"; export class FibonacciTests { @Test("fibonacci(1) doit être égal à 1") testFibonacci1() { let result = fibonacci(1) Expect(result).toBe(1); } @Test("fibonacci(2) doit être égal à 1") testFibonacci2() { let result = fibonacci(2) Expect(result).toBe(1); } }
-
Observons le contenu de ce fichier TypeScript :
-
Tout en haut, on utilise
import
pour aller chercher les fonctions fournies par Alsatian, et pour aller chercher la fonctionfibonacci()
que nous souhaitons tester. -
Ensuite on définit et on exporte une classe appelée
FibonacciTests
dans laquelle nous allons ranger tous nos tests. Nous n’allons pas voir dans le détail ce qu’est une classe, pour le moment retenez juste que c’est un endroit où nous allons ranger tous nos cas de tests. -
Enfin, on définit chaque cas de test d’une manière similaire à une fonction :
-
On écrit la signature du cas de test avec
@Test("description de mon test")
, suivi du nom de la fonction de test ; -
On écrit le contenu du cas de test entre accolades (
{}
), où on appelle la fonction à tester (ici,fibonacci
), et où on utilise les fonctions fournies par Altasian, à savoir :-
Expect
pour donner à Altasian le résultat obtenu, -
toBe
pour indiquer à Altasian quel est le résulta attendu.
-
-
-
Attention, un ensemble de cas de test ne peuvent pas être exécutés comme des fichier TypeScript normaux ! Voyons comment faire pour les exécuter.
1.3.2. Exécution simple via le terminal
Vous pouvez lancer les tests unitaires automatiquement en exécutant la commande suivante depuis un terminal :
npm test
Vous verrez s’afficher un compte rendu de l’exécution des tests : combien ont réussi, combien ont échoué, et lesquels ont échoué.
La commande npm test va en fait aller chercher la commande test au sein du fichier package.json ajouté précédemment.
Cette commande test exécute Alsatian sur tous les tests présents dans le répertoire tests .
|
1.3.3. Exécution et débogage via Visual Studio Code
Il est également possible d’exécuter les tests directement depuis l’interface graphique de Visual Studio Code sans avoir besoin d’un terminal. Cela nécessite d’ouvrir une vue appelée NPM scripts qui n’est pas ouverte par défaut dans l’interface.
-
Pour ouvrir la vue NPM scripts:
-
Portez votre regard en haut à gauche sur votre section Explorer, qui ressemble normalement à ceci :
-
Repérez en haut à gauche l’icône avec trois points, et cliquez dessus.
-
Un menu s’ouvre permettant de choisir quelles vues on souhaite afficher. Cliquez sur la vue NPM Scripts (la seule non activée) pour l’activer.
-
-
Attention, c’est très discret : constatez que vous avez désormais tout en bas de votre section Explorer une nouvelle vue repliée appelée NPM Scripts :
-
Cliquez dessus, et vous verrez alors une liste contenant uniquement le script
test
:
-
-
Pour lancer une exécution ou un déboguage :
-
Dans la vue NPM Scripts, mettez votre curseur sur la ligne avec le script
test
(sans cliquer dessus), -
Deux petites icônes s’affichent sur la droite :
-
L’icône "insecte" permet d’exécuter les tests en mode débogage, donc avec possibilité de mettre l’exécution en pause à l’aide de points d’arrêt, et possibilité d’exécuter ligne par ligne (voir section suivante du TP pour plus de détails),
-
L’icône "lecture" permet d’exécuter les tests normalement.
-
-
Lorsque vous lancez vos tests de cette manière, et que vos tests échouent, vous pouvez constater qu’un long message d’erreur comme celui-ci s’affiche alors :
Ce message d’erreur peut être ignoré, il est tout à fait normal qu’il s’affiche lorsqu’un test échoue. Mais il faut reconnaître que ce n’est pas très joli à voir ni très utile. Si vous souhaitez ne plus avoir ce message d’erreur, il suffit de créer à la racine de votre projet un fichier
|
1.4. Comment déboguer un test en pratique ?
Que faire lorsqu’un test est bien codé, mais que le test échoue ? Cela signifie qu’il existe un défaut dans le programme testé par le test, et qu’il faut le localiser puis le corriger !
Deux possibilités :
-
Soit on va lire les lignes de code du programme, et tenter de comprendre par cette simple lecture ce qui ne va pas. C’est souvent suffisant pour des problèmes simples.
-
Soit on utilise le débogueur pour exécuter le programme ligne par ligne, et pour observer en détail ce qu’il se passe, et comprendre ce qui ne fonctionne pas comme prévu.
Imaginons que l’on souhaite enquêter sur l’exécution du test testFibonnacci1
.
On souhaite utiliser le débogueur pour mieux comprendre ce qu’il se passe.
Voyons comment nous y prendre :
-
Mettez un point d’arrêt sur la première ligne de
testFibonnacci1
, c’est à dire la ligne avec un l’appel à la fonctionfibonacci()
. Pour cela, cliquez sur la colonne à gauche de la ligne, et cela fera apparaître un point rouge comme ceci : -
Lancez vos tests en mode débogage (voir la section suivante pour l’usage de la vue NPM Tests). L’exécution va très rapidement se mettre en pause sur la ligne contenant le point d’arrêt, ce qui donne ce résultat :
-
Utilisez le bon bouton de la mini-barre d’outils de débogage (ou bien la touche F11 directement) pour effectuer l’action Step Into. Cette action a pour but de rentrer à l’intérieur d’une fonction appelée sur la ligne actuellement en pause, qui est ici la fonction
fibonacci
. Autrement dit,Step Into
va poursuivre l’exécution très brièvement, et mettre de nouveau en pause au tout début de l’exécution de la fonctionfibonacci
. On arrive alors ici : -
L’enquête peut alors commencer ! Différents outils sont à notre disposition :
-
L’action Step Over qui permet d’exécuter la ligne actuellement en pause, et de passer à la ligne suivante. On peut ainsi exécuter notre fonction
fibonacci
ligne après ligne. -
L’action Step Into peut ici aussi être utilisée pour plonger à l’intérieur d’un appel de fonction, comme par exemple sur la ligne
return fibonacci(n-1)
afin de plonger dans le 2e appel effectué récursivement sur la fonctionfibonacci
. -
La vue Variables, située à gauche lorsqu’on est dans le mode Run, nous permet savoir ce que contiennent toutes nos variables. Pour fibonnacci, elle ressemble au départ à ceci :
On peut voir que la valeur de
n
est actuellement1
, ce qui est logique puisque la fonction a été appelée avecfibonacci(1)
. Mais le plus intéressant est que cette vue se mettra à jour à chaque exécution de ligne, ce qui permet de suivre exactement comment les variables évoluent !
-
Vous voilà parfaitement outillés pour enquêter sur les bugs que peuvent contenir vos programmes 😃.
1.5. Écriture de nouveaux tests
-
Dans le fichier
tests/math-tests.ts
que vous avez créé, ajoutez de nouveaux tests pour la fonctionfibonacci
. -
Exécutez vos tests. Est-ce qu’ils passent tous ?
-
Si certains de vos tests ne passent pas, trouvez l’erreur qui existe dans la fonction
fibonacci
, et corrigez là ! N’hésitez pas à aller voir la page Wikipédia sur la suite de Fibonacci pour comprendre ce que doit faire cette fonction. -
Relancez vos tests après votre correction. Ils doivent désormais tous passer 😃.
2. Écriture et test d’autres fonctions
Continuons avec de nouvelles fonctions et de nouveaux cas de tests.
2.1. Âge et Année bissextile
-
Écrire dans un fichier
.ts
le code d’une fonction qui calcule l’âge d’une personne, en faisant l’hypothèse que la date du jour est le 10/02/2020. Écrire les cas de tests possibles pour une telle fonction dans un fichier.ts
dans le répertoiretests
. -
Écrire dans un fichier
.ts
le code d’une fonction qui renvoietrue
si une année est bissextile. Écrire les cas de tests possibles pour une telle fonction dans un fichier.ts
dans le répertoiretests
.
2.2. Former un triangle
-
Étant données
3
longueurs, nous voulons vérifier que la construction d’untriangle est possible. Pour cela, nous allons écrire une fonctionisTriangle(a: number, b: number, c: number): boolean
qui renvoievrai
ssi il est possible de construire un triangle en utilisant les3
longueurs passées en paramètre. -
Écrire les cas de tests possibles pour une telle fonction dans un fichier
.ts
dans le répertoiretests
.
2.3. Entiers palindromes
-
Écrire une fonction qui permet d’écrire un entier à l’envers. Écrire les cas de tests possibles pour une telle fonction dans un fichier
.ts
dans le répertoiretests
. -
Écrire une fonction qui permet de vérifier qu’un entier est un palindrome. Écrire les cas de tests possibles pour une telle fonction dans un fichier
.ts
dans le répertoiretests
.