20  Laboratoires

À l’École de technologie supérieure, le cours de LOG210 propose un laboratoire de mise à niveau (nommé « lab 0 ») réalisé individuellement, où l’on passe à travers les différentes technologies utilisées dans le projet du laboratoire principal, qui, lui, est réalisé pendant le reste du cours en trois itérations de trois semaines. On peut trouver sur GitHub l’énoncé du lab0 et du laboratoire principal. Chaque équipe est libre de choisir parmi une liste d’exigences ce qu’elle veut réaliser dans chaque itération. Cela permet de pratiquer l’approche itérative en équipe. L’approche TDD est obligatoire (pour avoir des points pour une fonctionnalité réalisée).

Les deux premières itérations sont évaluées, mais les points pour les fonctionnalités réussies ne sont comptabilisés qu’à la dernière itération. Cela a plusieurs avantages pédagogiques :

Ce chapitre contient des informations sur le volet technique des laboratoires.

20.1 TypeScript

Qu’est-ce que TypeScript ? Selon Goldberg (2022), TypeScript comprend quatre éléments :

  • Un langage de programmation ayant toute la syntaxe de JavaScript, plus une syntaxe propre à TypeScript pour définir et utiliser les types ;
  • Un vérificateur de type pouvant décortiquer un ensemble de fichiers en JavaScript et en TypeScript définissant des variables, des fonctions, etc., afin d’indiquer d’éventuels problèmes de configuration ;
  • Un compilateur qui
    • invoque le vérificateur de type,
    • signale des problèmes si nécessaire et
    • finalement génère du code en JavaScript équivalent ;
  • Un service de langage qui transmet des informations provenant du vérificateur de type à l’IDE pour que ce dernier puisse faciliter le développement.

20.2 JavaScript/TypeScript

Pour la personne ayant déjà des connaissances de Java et des patterns GoF, Gamma, Helm, Johnson, et Vlissides (1994), il est recommandé d’apprendre les choses dans cet ordre :

Voici des points importants pour le projet de laboratoire, organisés pour quelqu’un ayant déjà des connaissances en Java :

  • TypeScript se traduit (« emits ») en JavaScript, alors il faut comprendre le moteur d’exécution JavaScript.
  • Pour convertir une chaîne en nombre, pour lire ou écrire un fichier sur disque, etc., on utilise des opérations en JavaScript.
  • Un type en TypeScript est comme un ensemble de valeurs plutôt qu’une définition hiérarchique. En Java, il n’est pas possible d’avoir un type pouvant être soit une chaîne soit un nombre. Mais, en TypeScript, c’est facile de déclarer un type comme une union de plusieurs types, par exemple string | number.
  • JavaScript a des notions de « truthy » et « falsy » (conversion d’une expression en une valeur booléenne) permettant de vérifier avec moins de code si une variable est définie ou initialisée, etc.
  • L’opérateur d’égalité stricte (===) (sans conversion de type).
  • Les fonctions fléchées (fat arrow functions en anglais).
  • Le traitement asynchrone en JavaScript :
  • Les services REST (GET vs PUT).
  • Environnement de test (Jest).
  • Les gabarits (templates) Pug (anciennement Jade) : Tutoriel (court) , Tutoriel (plus complet) .
  • Bootstrap (mise en page avec CSS) : Tutoriel (attention, il faut appliquer les éléments dans les gabarits Pug) .

Le lab 0 aborde plusieurs de ces aspects, mais certaines notions sont plus complexes et nécessitent une étude approfondie. Le but de cette section est de donner des tutoriels plus spécifiques. Enseigner la syntaxe ou les principes du langage TypeScript n’est pas le but de ce manuel, mais apprendre à trouver l’information soi-même est essentiel pour une personne travaillant dans les technologies de l’information.

Il y a un dépôt d’exemples avec TypeScript (utilisant ts-node pour les voir facilement) sur GitHub. Il y a un exemple qui montre comment faire des REST à partir de TypeScript avec le système SGB.

20.3 JavaScript : Truthy et Falsy (conversion en valeur booléenne)

JavaScript offre un mécanisme simple pour vérifier des valeurs dans une expression if. Imaginez l’exemple suivant :

let maVariable;

// d'autres instructions...

if (maVariable != undefined 
    && maVariable != null 
    && maVariable != '') {
  // on peut faire quelque chose avec maVariable...
}

On vérifie trois possibilités pour maVariable avant de l’utiliser. Ce genre de situation arrive souvent en JavaScript, puisque les objets peuvent prendre des valeurs différentes selon le contexte. Contrairement à Java, les types des variables JavaScript peuvent changer dynamiquement. Il serait bien de pouvoir réduire la quantité de code dans ces cas.

Grâce à la notion de conversion de valeur selon la règle de « truthy » et « falsy », JavaScript permet de simplifier les instructions en une seule condition, sans ET (&&), en convertissant la valeur de maVariable en booléenne true ou false :

// conversion booléenne selon la règle de « truthy » et « falsy »
if (maVariable) {
  // on peut faire quelque chose avec maVariable...
}

Il faut comprendre la règle de conversion en valeur booléenne selon « truthy » et « falsy ». En fait, il est plus simple de commencer par les valeurs se traduisant en false (« falsy »), car tout ce qui ne l’est pas est donc true (« truthy »).

20.3.1 Falsy

Les valeurs suivantes se convertissent en false dans une condition :

  • false
  • null
  • undefined
  • 0 (attention, c’est parfois un piège)
  • NaN (not a number)
  • '' ou "" (chaîne vide)

20.3.2 Truthy

Tout ce qui n’est pas converti en false (expliqué ci-dessus) est converti en true. En voici quelques exemples :

  • {} (objet vide)
  • [] (tableau vide)
  • -20
  • etc.
Mise en garde

N’oubliez pas que la valeur de 0 est « falsy » dans une condition. C’est souvent un piège en JavaScript quand on considère les variables qui peuvent avoir une valeur numérique. Par exemple, si l’on fait if (maVariable) pour tester si une variable est définie, si la variable est définie et que sa valeur est 0, la condition sera false.

20.4 Git

Git est un logiciel de gestion des versions permettant de stocker un ensemble de fichiers en conservant la chronologie de tous les changements ayant été effectués dessus. Ce genre de logiciel permet de retrouver les différentes versions d’un lot de fichiers connexes. Depuis 2010, Git est le logiciel de gestion des versions le plus populaire, disponible sur les environnements Windows, Mac et Linux. Il s’agit d’un logiciel libre et gratuit, créé en 2005 par Linus Torvalds, fondateur du noyau Linux. Linus Torvalds prononce Git avec un g dur (Google, 2007).

Git est particulier parce qu’il est décentralisé, utilisant un système de connexion pair à pair. Les fichiers informatiques sont stockés sur l’ordinateur de chaque personne qui contribue au projet et ils peuvent également l’être sur un serveur dédié comme GitHub, GitLab, Bitbucket, etc.

Puisque chaque personne est libre de modifier les fichiers comme elle le veut, sans être bloquée par les autres contributeurs et contributrices, il est nécessaire de synchroniser et de fusionner les contributions de temps en temps. Cette synchronisation peut être plus ou moins compliquée, selon les travaux réalisés par chaque personne, par exemple lorsque deux entre elles ont modifié un même fichier sur leur ordinateur. Une des forces de Git est l’ensemble des fonctionnalités permettant de gérer tous les cas de synchronisation. Mais cet avantage peut aussi faire en sorte que Git soit compliqué à utiliser. La figure 20.1 présente un survol des concepts et des opérations de base de Git.

Ce manuel ne rentre pas dans les détails de chaque opération Git ; il existe plusieurs tutoriels pour Git sur Internet. Il y a beaucoup de scénarios où Git peut être utile, par exemple pour récupérer une version antérieure d’un fichier ou pour savoir qui a apporté une modification à un fichier, etc. Apprendre tous les cas d’utilisation de Git serait long et inintéressant. Il n’est pas nécessaire de tout comprendre pour commencer.

Figure 20.1: Concepts et opérations de base de Git. « Basic Git Concepts and Operations » de Costa Shulyupin, utilisé sous EPL.

20.5 Évaluer les contributions des membres de l’équipe

Il existe un outil nommé gitinspector qui peut indiquer le niveau d’implication des membres de l’équipe dans un projet sur GitHub. Étant donné que les laboratoires de ce manuel utilisent un squelette avec les tests, les fichiers src de TypeScript, les modèles PlantUML et le README.md, il est possible d’utiliser gitinspector pour voir des rapports de contribution sur chacun des volets.

Pour faciliter l’utilisation de l’outil, le professeur Fuhrman a créé un script en bash. Voici comment l’utiliser :

  • Installer gitinspector dans npm avec la commande npm install -g gitinspector ;
  • Télécharger le script :
git clone \
https://gist.github.com/fuhrmanator/b5b098470e7ec4536c35ca1ce3592853 \
contributions
Cloning into 'contributions'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 10 (delta 3), reused 7 (delta 2), pack-reused 0
Unpacking objects: 100% (10/10), 2.02 KiB | 82.00 KiB/s, done.
  • Lancer le script sur un dépôt de code source, par exemple sga-equipe-g02-equipe-4 :
cd contributions
./contributions.sh ../sga-equipe-g02-equipe-4/
gitinspector running on ../sga-equipe-g02-equipe-4/: patience...
ContributionsÉquipeTest.html
ContributionsÉquipeModèles.html
ContributionsÉquipeDocs.html
ContributionsÉquipeTypeScript.html
ContributionsÉquipeViews.html

Les fichiers .html sont créés pour les contributions Test, Modèles, Docs, TypeScript et Views. Chaque rapport indique les contributions selon deux perspectives :

  1. Le nombre de soumissions par auteur ou auteure (activité Git) ;
  2. Le nombre de lignes par auteur ou auteure encore présentes et intactes dans la version HEAD.

Vous pouvez voir un exemple de rapport à la figure 20.2.

Figure 20.2: Exemple de rapport généré par gitinspector.

20.5.1 Faire le bilan de la contribution de chaque membre

Après l’évaluation à la fin de chaque itération, il est important de quantifier et de considérer la contribution de chacun et chacune au projet et de valider avec les responsabilités prévues dans le plan de l’itération. Il est normal d’avoir un écart entre le travail prévu et le travail effectué. Un des objectifs du bilan est d’essayer d’expliquer les gros écarts et de corriger ou mitiger les problèmes.

Par exemple, on peut voir sur la figure 20.2 qu’Anne et Justin ont fait une contribution beaucoup plus importante que Francis et Mélanie. Dans le bilan de l’itération, on doit indiquer explicitement ce fait, même avec des pourcentages.

Important

Une phrase vague comme « des membres ont travaillé plus que d’autres » est une formulation diplomatique, mais elle n’est pas assez explicite et n’est pas une résolution proactive du problème, si nécessaire.

20.5.2 Proposer des solutions au besoin

Une inégalité importante dans les contributions est un signal d’alarme. On doit agir, mais on commence par poser des questions, par exemple :

  • Est-ce que Francis et Mélanie sont à l’aise avec les technologies utilisées dans le lab ? Ont-ils besoin de coaching ?
  • Sont-ils des « parasites » ou des « mollassons » (Oakley, Felder, Brent, et Elhajj, 2004) (traduction française de l’article) ? À certaines universités, le plan de cours vous permet d’exclure leurs noms du rapport (et ils auront une note de zéro pour la remise), mais seulement s’ils n’ont rien fait du tout (ce qui n’est pas le cas dans l’exemple ci-dessus). Une personne exclue de cette manière va probablement abandonner le cours, et vous perdrez définitivement un ou une membre de l’équipe.
  • Est-ce qu’Anne et Justin ont laissé suffisamment de liberté aux autres pour faire une contribution importante ? Font-ils assez confiance aux autres ?
  • Avez-vous fait un plan d’itération assez détaillé pour que chaque membre puisse contribuer adéquatement ? Dans l’exemple ci-dessus, peut-être Francis et Mélanie ont-ils trouvé ça difficile de savoir où contribuer ?
  • Est-ce que tout le monde assiste aux séances de laboratoire ?
  • Est-ce que tout le monde travaille au moins 6 heures en dehors des séances encadrées ?
  • Est-ce que certaines personnes travaillent excessivement, sans donner la chance aux autres de contribuer ? N’oubliez pas que les laboratoires sont une manière d’apprendre à pratiquer la matière de ce manuel. Laisser un ou deux membres de l’équipe faire plus de travail peut nuire à la valeur pédagogique des laboratoires (ça peut faire mal à l’examen final pour les membres qui ont moins contribué). Il y a aussi un risque sur le plan de la Redondance des compétences dans l’équipe (bus factor), surtout si une personne qui travaille beaucoup plus que les autres éprouve un problème d’épuisement à cause du fait qu’elle travaille trop.
  • Est-ce que tout le monde utilise un moyen de communication de manière synchrone et asynchrone (Slack, Discord, Teams, etc.) ? Le courriel n’est pas l’outil idéal pour coordonner un travail en équipe.
  • Etc.

Dans le bilan, il faut constater les faits et proposer des solutions pour éviter des inégalités importantes sur le plan de la contribution dans les prochaines itérations. Ainsi, vous gérerez les problèmes de manière plus proactive.

20.5.3 FAQ pour gitinspector

Q : Comment fusionner le travail réalisé par une même personne, mais avec plusieurs comptes (courriels) différents ?

R : La solution est avec le fichier .mailmap. Vous pouvez rapidement générer un fichier de base avec la commande :

git shortlog -se | sed "s/^.*\\t//"  > .mailmap

Ensuite, modifiez le fichier .mailmap pour respecter ce format :

Par exemple, le .mailmap initial qui contient quatre entrées pour le même auteur :

On décide de garder l’alias C. Fuhrman <christopher.fuhrman@etsmtl.ca> pour chaque nom :

Le nom que vous mettez sera celui qui apparaît dans les rapports la prochaine fois qu’ils seront générés.

Q : Comment exclure le travail réalisé par un(e) chargé(e) de laboratoire (par exemple le clone initial dans GitHub Classroom) ?

R : La solution est d’ajouter le nom de l’auteur ou de l’auteure dans le tableau du script contributions.sh à la ligne suivante avec authorsToExcludeArray. Attention :

  • Il n’y a pas de , entre les éléments des tableaux en bash.
  • Un nom contenant un accent ne sera pas reconnu. Il faut changer le nom dans le .mailmap pour qu’il n’y ait pas d’accents, ou utiliser une chaîne partielle comme "Benjamin Le" pour exclure les contributions de "Benjamin Le Dû".
authorsToExcludeArray=("C. Fuhrman" "Benjamin Le" "Yvan Ross")

Q : J’ai une autre question…

R : Il y a aussi une FAQ sur le dépôt de gitinspector.