# Testing automatisé avec Mocha Les tests automatisés seront utilisés dans d'autres tâches. Ils sont également largement utilisés dans des projets réels. ## Pourquoi avons-nous besoin de tests ? Lorsque nous écrivons une fonction, nous pouvons généralement imaginer ce qu’elle doit faire : quels paramètres donnent quels résultats. Au cours du développement, nous pouvons vérifier la fonction en l'exécutant et en comparant le résultat obtenu. Par exemple, nous pouvons le faire dans la console. Si quelque chose ne va pas -- alors nous corrigeons le code, exécutons à nouveau, vérifions le résultat -- et ainsi de suite jusqu'à ce que cela fonctionne. Mais de telles "ré-exécutions" manuelles sont imparfaites. **Lors du test manuel d’un code, il est facile de rater quelque chose.** Par exemple, nous créons une fonction `f`. On écrit du code, on teste : `f(1)` fonctionne, mais `f(2)` ne fonctionne pas. Nous corrigeons le code et maintenant `f(2)` fonctionne. Cela semble complet ? Mais nous avons oublié de re-tester `f(1).` Cela peut conduire à une erreur. C’est très typique. Lorsque nous développons quelque chose, nous gardons à l’esprit beaucoup de cas d’utilisation possibles. Mais il est difficile de s’attendre à ce qu’un programmeur les vérifie manuellement après chaque modification. Il devient donc facile de réparer une chose et d'en casser une autre. **Le test automatisé signifie que les tests sont écrits séparément, en plus du code. Ils exécutent nos fonctions de différentes manières et comparent les résultats avec les attentes.** ## Behavior Driven Development (BDD) Commençons par une technique nommée [Behavior Driven Development](https://fr.wikipedia.org/wiki/Behavior-driven_development) ou, en bref, BDD. **BDD, c'est trois choses en une : les tests ET la documentation ET les exemples.** Pour comprendre BDD, examinons un cas pratique de développement. ## Développement de "pow": la spec Imaginons que nous voulions créer une fonction `pow(x, n)` qui élève `x` à la puissance d'un entier `n`. Nous supposons que `n≥0`. Cette tâche n’est qu’un exemple : il existe l’opérateur `**` en JavaScript qui peut le faire, mais nous nous concentrons ici sur le flux de développement pouvant également s’appliquer à des tâches plus complexes. Avant de créer le code de `pow`, nous pouvons imaginer ce que la fonction devrait faire et la décrire. Cette description s'appelle une *spécification* ou, en bref, une **spec**, et contient des descriptions de cas d'utilisation ainsi que des tests pour ceux-ci, comme ceci : ```js describe("pow", function() { it("raises to n-th power", function() { assert.equal(pow(2, 3), 8); }); }); ``` Une spécification a trois blocs de construction principaux que vous pouvez voir ci-dessus : `describe("title", function() { ... })` : Quelle fonctionnalité nous décrivons. Dans notre cas, nous décrivons la fonction `pow`, utilisée pour grouper les "workers" -- le bloc `it`. `it("use case description", function() { ... })` : Dans le titre de `it`, nous décrivons d'une *manière lisible par l'homme* le cas particulier d'utilisation, et le deuxième argument est une fonction qui le teste. `assert.equal(value1, value2)` : Le code à l'intérieur du bloc `it`, si l'implémentation est correcte, doit s'exécuter sans erreur. Les fonctions `assert.*` sont utilisées pour vérifier si `pow` fonctionne comme prévu. Ici, nous utilisons l’un d’eux - `assert.equal`, qui compare les arguments et génère une erreur s’ils ne sont pas égaux. Ici, il vérifie que le résultat de `pow(2, 3)` est égal à `8`. Nous ajouterons plus tard d'autres types de comparaisons et de contrôles. La spécification peut être exécutée et le test spécifié dans le bloc `it` sera exécuté. Nous verrons cela plus tard. ## Le flux de développement Le flux de développement ressemble généralement à ceci : 1. Une spécification initiale est écrite, avec des tests pour les fonctionnalités les plus élémentaires. 2. Une implémentation initiale est créée. 3. Pour vérifier si cela fonctionne, nous exécutons le framework de test [Mocha](https://mochajs.org/) (plus de détails bientôt) qui exécute la spécification. Tant que la fonctionnalité n'est pas complète, des erreurs sont affichées. Nous apportons des corrections jusqu'à ce que tout fonctionne. 4. Nous avons maintenant une implémentation initiale de travail avec des tests. 5. Nous ajoutons d'autres cas d'utilisation à la spécification, probablement pas encore pris en charge par les implémentations. Les tests commencent à échouer. 6. Passez à l'étape 3, mettez à jour l'implémentation jusqu'à ce que les tests ne génèrent aucune erreur. 7. Répétez les étapes 3 à 6 jusqu'à ce que la fonctionnalité soit prête. Donc, le développement est *itératif*. Nous écrivons la spécification, la mettons en œuvre, nous nous assurons que les tests réussissent, puis rédigeons d'autres tests, nous nous assurons qu'ils fonctionnent, etc. À la fin, nous avons une implémentation qui fonctionne et des tests. Voyons ce flux de développement dans notre cas pratique. La première étape est déjà terminée : nous avons une spécification initiale pour `pow`. Maintenant, avant de procéder à l’implémentation, utilisons quelques bibliothèques JavaScript pour exécuter les tests, histoire de voir qu’elles fonctionnent (elles échoueront toutes). ## La spec en action Dans ce tutoriel, nous utiliserons les bibliothèques JavaScript suivantes pour les tests : - [Mocha](https://mochajs.org/) -- le framework central : il fournit des fonctions de test communes, y compris `describe`, et `it` ainsi que la fonction principale qui exécute les tests. - [Chai](https://chaijs.com) -- la bibliothèque avec de nombreuses affirmations. Elle permet d’utiliser beaucoup d’affirmations différentes, pour le moment nous n’avons besoin que de `assert.equal`. - [Sinon](https://sinonjs.org/) -- une bibliothèque pour espionner des fonctions, émuler des fonctions intégrées et plus encore, nous en aurons besoin beaucoup plus tard. Ces bibliothèques conviennent aux tests sur le navigateur et sur le serveur. Ici, nous allons considérer la variante du navigateur. La page HTML complète avec ces frameworks et `pow` spec : ```html src="index.html" ``` La page peut être divisée en quatre parties : 1. Le `` -- ajouter des bibliothèques et des styles tiers pour les tests. 2. Le `