Cours Node.js Cours Node.js - Partie 5 - Validation, tests automatisés et intégration continue

Objectifs de cette partie

Afin de savoir développer et maintenir une application Node.js de manière pérenne, nous allons:

Prérequis:

Durée estimée: 4 heures.

Pré-requis

Pour effectuer ces exercices, assurez-vous que les pré-requis suivants sont bien installés et accessibles depuis votre shell Linux:


Introduction

La plupart des applications sont amenées à fonctionner pendant plusieurs années. L’évolution des besoins des utilisateurs, des entreprises, ainsi que l’évolution des technologies et des normes de sécurité implique que le code source de ces applications devra être modifié régulièrement. Notamment pour y ajouter des fonctionnalités et corriger des bugs. Afin d’éviter que la maintenance d’un programme ne devienne de plus en plus coûteuse et risquée, il faut suivre quelques règles d’hygiène, parmi lesquelles: tester régulièrement l’application.

Pour vérifier que les fonctionnalités d’un programme se comportent comme prévu, il est possible de le tester “à la main”. C’est à dire: d’interagir manuellement avec ce programme, via son (ou ses) interface(s). Par exemple, dans le cas d’un site statique, il suffit de consulter le site à l’aide de plusieurs navigateurs, et d’explorer ses pages pour s’assurer que le contenu s’affiche comme prévu. Dans le cas d’un site dynamique – ou pire: d’un site dynamique avec compte utilisateurs – il y a beaucoup plus de cas à tester. Il faut en effet vérifier que les procédure de création de compte utilisateur, d’identification et d’oubli de mot de passe fonctionnent bien, mais aussi que les informations stockées en base de données ne sont visibles qu’aux utilisateurs qui sont sensés y avoir accès.

L’écriture de tests automatisés permet de définir une fois pour toutes cette liste de vérifications à mener, pour vérifier qu’un site (ou programme) fonctionne comme prévu, sans avoir à effectuer d’opérations manuelles répétitives.

Il existe trois grandes catégories de tests:


Exercice 1 - Des tests pour vérifier la conformité

Consultez le fichier 7-complete.spec.js. (en cliquant sur le lien)

Il s’agit d’une suite de tests conçue pour être exécutée par le framework de tests “Mocha”. (on peut également le qualifier de test runner ou test driver)

Commencez par observer attentivement le titre donné à chaque test, et la manière dont ces titres ont été formulés.

Puis répondez aux questions suivantes:


Exercice 2 - Des tests pour éviter les régressions

Dans l’exercice 1, nous avons vu un premier exemple de suite de tests automatisés permettant de vérifier la conformité de programmes avec des exigences fonctionnelles et techniques. Dans cet exemple, les tests ont été conçus pour être les plus agnostiques possibles quant à la manière d’écrire le code testé.

Nous allons maintenant voir d’autres exemples de tests automatisés, pour une finalité différente: éviter les régressions qui pourraient être apportées par les contributeurs d’un projet open source.

Consultez le code source du projet Openwhyd puis répondez aux questions suivantes:


Exercice 3 - Écrire des tests unitaires

Dans cet exercice, vous allez définir puis implémenter quelques tests unitaires, afin de vérifier le fonctionnement attendu de la fonction JavaScript suivante:

// La fonction somme() retourne la somme des nombres passés en paramètre.
// Tout paramètre manquant aura 0 comme valeur par défaut.
// Si un des paramètre n'est pas de type `number`, la fonction lèvera une
// exception avec le message d'erreur "paramètre invalide".
function somme(nombre1, nombre2) {
  // (implémentation de la fonction: non nécessaire pour cet exercice)
}

Étapes:

  1. En vous appuyant sur la signature de la fonction somme() et de sa documentation fournie en commentaires, proposer 3 intitulés de tests unitaires pour cette fonction, en respectant la forme suivante:

    Avec les valeurs de paramètres X et Y,
    la fonction somme() est sensée retrourner la valeur Z

    Remplacer X, Y et Z par de vraies valeurs.

  2. Après avoir formulé en français ces trois intitulés, implémenter les tests unitaires correspondants en JavaScript, dans un fichier test.js, de manière à ce qu’ils soient compréhensibles par Mocha.

  3. Dans le même fichier, ajouter la fonction somme() fournie ci-dessus, telle quelle. Exécuter la suite de tests avec Mocha. Tous les tests devraient échouer, car la fonction n’est pas encore implémentée.

  4. Compléter l’implémentation de la fonction somme() de manière à ce qu’elle fonctionne comme prévu. Vérifier que tous les tests passent, désormais.

  5. Si ce n’est pas encore fait, initialiser puis compléter le fichier package.json pour que n’importe quel autre développeur puisse lancer vos tests depuis sa machine, en tapant seulement les commandes npm install et npm test.


Exercice 4 - Écrire un test de bout en bout

Dans cet exercice, vous allez définir puis implémenter un test de bout en bout pour vérifier le bon fonctionnement d’une des routes du chatbot que nous avons développé dans la partie 1 du cours.

Dans ce contexte, il est approprié d’employer un test de bout en bout car ce test pourrait très bien être effectué manuellement par n’importe quel utilisateur de votre API, sans nécessiter d’accès au code source de cette API. Par contre, pour que votre test puisse fonctionner, il faudra que l’API soit active, prête à répondre aux requêtes.

Voici l’intitulé du test que vous allez implémenter: Quand le chatbot reçoit une requête HTTP GET à la racine (/), il répond “Bonjour !”.

Implémenter ce test, le lancer avec Mocha et vérifier qu’il passe quand votre serveur de chatbot est actif.


Exercice 5 - Outils pour améliorer la qualité du code

Plus le code est simple et lisible, plus il sera facile à maintenir. Plus le code est facile à maintenir, moins il sera vulnérable aux bugs, dans la durée.

Dans cet exercice, vous allez installer 3 outils qui vont vous aider à améliorer la qualité de votre code:

Étapes à effectuer dans le répertoire de l’exercice précédent:

  1. Installez ESLint à l’aide de la commande $ npx eslint --init, en choisissant les options suivantes:
  1. Exécutez ESLint sur vos fichiers JS ($ npx eslint *.js) puis appliquez les modifications suggérées pour améliorer votre code.

Si ESLint ne suggère aucune modification dans votre code, causez volontairement un problème: utilisez un = au lieu de l’opérateur d’égalité === employé dans une des conditions if de server.js, sauvegardez puis relancez la commande.

  1. Installez Prettier: $ npm install --save-dev prettier

  2. Demandez à Prettier de lister les lignes qui mériteraient d’être mises en forme: $ npx prettier server.js | diff server.js -

  3. Demandez à Prettier de mettre en forme (reformater) vos fichiers JS: $ npx prettier --write *.js

  4. Pour éviter que les règles de ESLint n’entrent en conflit avec celles de Prettier, installez la configuration eslint-config-prettier en suivant ces instructions

  5. Installez TypeScript: $ npm install --save-dev typescript puis $ $(npm bin)/tsc --init

  6. Exécutez TypeScript ($ $(npm bin)/tsc) pour voir s’il y a erreurs de types à corriger dans votre code JavaScript

Vous devrez paramétrer les options suivantes dans tsconfig.json:

  1. Modifiez package.json de manière à ce qu’il suffise de taper npm run check pour afficher les suggestions de ESLint, Prettier et TypeScript

  2. BONUS: Installez l’éditeur de code Visual Studio Code, ouvrez le répertoire de l’exercice, puis configurez le workspace de votre projet de manière à ce que:


Exercice 6 - Mise en place d’intégration continue avec GitHub Actions

L’intégration continue est un ensemble de pratiques permettant de développer de manière plus rapide et robuste. Elle vise notamment à prévenir les régressions – c’est à dire les modifications de code qui introduisent des défauts là où il n’y en avait pas – de manière continue.

Pour prévenir ces régressions, nous allons mettre en place un processus qui exécutera automatiquement nos tests automatisés à chaque fois que nous enverrons des changements de code à notre dépôt distant. (c.a.d. git commit suivi de git push)

Pour cela, nous allons configurer GitHub Actions, le système d’intégration continue mis à disposition gratuitement par GitHub.

Objectifs

GitHub Actions exécutera la suite de tests automatisés de l’exercice 3 et nous informera des résultats:


Pour aller plus loin

Ressources sur la maintenabilité, les tests et l’Artisanat Logiciel (Software Crafts(wo)manship):

Références sur les outils de qualité de code: