Aller au contenu

Tests semi-automatiques de tous les IDEs de la documentation#

À partir de la version 2.3.0, le thème propose de générer une page spécifique, depuis laquelle il est possible de tester automatiquement tous les IDEs créés dans la documentation, en exécutant leur section corr en lieu et place de la section code.

Mise en place#

Dans le cas d'une utilisation en local durant mkdocs serve (voir plus bas pour une utilisation sur le site construit via un pipeline), il suffit d'ajouter le réglage ci-dessous à la configuration du plugin pyodide_macros dans le fichier mkdocs.yml :


plugins:
    pyodide_macros:
        testing:
            include: serve


Ceci va automatiquement inclure à la racine de la documentation une page test_ides/ (ou bien test_ides.html si le réglage use_directory_urls: false est utilisé dans le fichier mkdocs.yml).

Cette page contient un IDE vide, ainsi qu'une liste de tous les IDEs utilisés dans les autres pages de la documentation, et les informations et fonctionnalités associées aux tests :


L'interface de la page de test des IDEs de la documentation

Interface sous l'IDE#

Les boutons supérieurs :

Ces quatre boutons sont des filtres, permettant d'afficher ou non les éléments correspondant à l'état du bouton.

Noter que :

  • Le filtre des succès contrôle les deux types de succès: et .
  • S'il y a beaucoup de tests, l'affichage peut être long à se mettre à jour.


Sur la gauche :

  • Le bouton play en haut à gauche, permet de lancer tous les tests pour les IDEs actuellement sélectionnés (qu'ils aient déjà été testés ou non).

  • Le bouton stop juste à côté permet de stopper les tests, une fois que le test en cours est terminé.

  • Suivent un certain nombre de compteurs :

    1. IDEs found : nombre d'IDEs trouvés dans toute la documentation.
    2. Skip : nombre d'IDEs non testés (indiqués par dans l'interface. Voir aussi comment configurer le test d'un IDE plus bas dans la page).
    3. To do : nombre d'IDEs sélectionnés mais non encore testés ( ).
    4. Success : nombre d'IDEs ayant passé les tests sans erreur ( ou , voir la configuration de test d'un IDE).
    5. Error : nombre d'IDEs ayant échoué les tests ( ).
  • Puis trois boutons:


Zone centrale :

La zone centrale présente une liste de liens associés à chaque IDE de la documentation.
Les noms sont construits en indiquant la page contenant l'IDE, concaténée avec la chaîne utilisée pour l'argument py_name, dans l'appel de macro IDE, ainsi que l'argument ID s'il a été utilisé.


Sur la droite :

La partie droite contient :

  • L'état de l'IDE en question vis-à-vis des tests :

    État Signification
    Non testé
    À tester
    OK (pas d'erreur)
    OK (erreur voulue)
    Échec
  • Un bouton download, permettant de charger l'intégralité de la configuration de l'IDE et les codes associés, dans celui en haut de la page de tests.
    Noter que ce bouton peut être absent, selon les réglages utilisés pour testing.include et testing.load_buttons.

    Toutes les sections d'environnement, les restrictions, les tests de validations, ... sont utilisées comme dans l'IDE d'origine.
    L'éditeur est par contre complété en y insérant :

    • le contenu de la section qui est testée (corr ou code, selon comment l'argument TEST de l'IDE est défini)
    • toutes les autres sections non vides (env, env_term, code, post_term, post) sont ensuite insérées dans une chaîne multilignes, afin que l'intégralité des codes de l'IDE soient visibles.
  • Un bouton play, qui permet de relancer le test de cet IDE uniquement.

  • Un ensemble de cases à cocher (désactivées) permettant de savoir quelles sections sont utilisées pour cet IDE. Les noms de sections sont affichés au survol de la souris. Un halo orange met en évidence la section qui sera lancée lors des tests (généralement, la section corr, mais cela peut être aussi la section code, selon la configuration du test).
    La présence/absence de fichiers REM.md ou VIS_REM.md est également indiquée.

Fonctionnement des tests#

Déroulé#

Les tests sont exécutés dans l'ordre des IDEs affichés dans la zone centrale.

Pour chaque IDE testé, les opérations effectuées sont les suivantes :

  1. Chargement des données de l'IDE, et mise en place de sa configuration complète (toutes les données passées en argument à la macro: codes python, SANS, REC_LIMIT, ...).
  2. Effacement du contenu du terminal.
  3. Affiche le nom de l'IDE testé dans le terminal.
  4. Réinitialise l'environnement pyodide (en utilisant clear_scope), sauf si l'IDE est configuré pour ne pas le faire.
  5. Met en place les outils spéciaux pour les tests.
  6. Lance une validation :
    • Les sections d'environnement sont exécutées comme pour une validation normale.
    • Utilise la section corr (même si elle n'a pas été définie) au lieu de la section code. Il peut être intéressant de configurer les IDEs n'ayant pas de section corr pour utiliser la section code à la place, ou encore pour que ces IDEs soient ignorés. L'option de configuration testing.empty_section_fallback peut également être mise à profit pour configurer ce type de comportement de manière plus globale.
    • Le décompte d'essais, et les affichages spéciaux liés à la révélation des corrections et remarques sont ignorés.
  7. Supprime les "outils spéciaux".
  8. Gère le résultat du test, en mettant à jour les compteurs et l'état de la case à cocher du test en cours.


Une fois tous les tests terminés, le contenu du terminal issu du dernier test reste affiché, et le temps total d'exécution est affiché en plus.

Les erreurs#

Lors des tests, le terminal de l'IDE en haut de la page affiche les messages comme le ferait l'IDE d'origine.

Si un test échoue, outre la mise à jour de l'état du test (case à cocher comme celles utilisées dans les QCMs), un message d'erreur détaillé est affiché en plus dans la console du navigateur (accessible via le raccourci F12 ), précédé par le lien vers l'IDE en question. Ceci permet d'analyser à posteriori les erreurs rencontrées.

Il est également possible de rejouer un test en particulier en cliquant sur le bouton play qui lui est associé, pour pouvoir voir ce qui a est affiché dans le terminal durant les exécutions.


Outils spéciaux#

Un certain nombre de modifications sont apportées à l'environnement d'exécution, de manière à adapter au mieux certaines fonctionnalités qui pourraient être spécifiques à la page markdown d'origine contenant l'IDE testé.

Il n'est cependant pas possible de couvrir tous les cas, et certains IDEs ne pourront pas être testés avec succès. Dans ces cas là, utiliser l'argument TEST="skip" dans l'appel de macros de l'IDE concerné permet de ne pas tester celui-ci.


Voici les fonctionnalités altérées pour les exécutions des tests :

Mermaid, Matplotlib

  • La fonction mermaid_figure est toujours accessible dans la page de tests, quel que soit l'IDE testé actuellement.
  • Les autres fonctionnalités relatives à ces outils ne sont pas modifiées en elles-mêmes, mais elles peuvent être affectées par la modification du module js de pyodide (voir ci-dessous).

import

La fonction d'importation de modules est modifiée de manière à contrôler ce qui est effectivement importés durant les tests :

  • Tout import du module js renverra un objet fake_js (voir ci-dessous).
  • Tout import de pyodide.http.pyfetch renverra une fonction alternative permettant de gérer les redirections automatiques pour les requêtes utilisant des adresses relatives.

Le module js de pyodide

Un objet fake_js est renvoyé lors d'un import js.
Cet objet se comporte comme le module d'origine excepté dans deux cas :

  • js.fetch est remplacé par une fonction alternative permettant de gérer les redirections automatiques pour les requêtes avec des adresses relatives.
  • js.document renvoie un objet "siphon" équivalent à un Mock : tout accès de propriétés, appels de méthodes, ou modifications de propriétés sur ces objets (récursivement) n'auront plus aucun effet. Ceci permet d'éviter que les tentatives de modification du DOM sur des éléments inexistant ne fassent échouer les tests alors que c'est le reste du code que l'on veut tester.

Redirections automatiques de requêtes internes utilisant des adresses relatives

Comme évoqué dans les points précédents, les fonctions js.fetch et pyodide.http.pyfetch sont remplacées par des fonctions qui analysent l'adresse passée en argument avant de relayer la requête à la fonction d'origine : si l'adresse est identifiée comme étant une adresse relative, elle est modifiée automatiquement de manière à récupérer le fichier à son adresse réelle sur le serveur, depuis la page des tests.

Sont considérées comme relatives toutes les addresses qui ne commencent pas par l'un des préfixes suivants :

  • http://
  • https://
  • ftp://
  • ftps://
  • file://
  • www.

Fonction de téléchargement ou téléversement

Ces fonctions sont laissées intactes, ce qui veut dire que si les IDEs concernés sont testés :

  • L'utilisateur devra rester devant son écran pour choisir les fichiers à téléverser.
  • Après chaque sélection de fichier, il faudra cliquer dans l'interface, pour éviter le "bug" lié aux actions utilisateurs.
  • Des fichiers seront créés sur le disque de l'utilisateur si le test engage la fonction de téléchargement.

Il peut être intéressant d'utiliser l'argument TEST="human" pour ces IDEs.

Configurations...#

...de la page de tests#

Les réglages disponibles, avec leurs valeurs par défaut sont :

plugins:
    - pyodide_macros:
        testing:
            empty_section_fallback: "skip"
            include: "null"
            load_buttons: null
            page: "test_ides"


Les points notables sont les suivants :

  • Pour un travail en local, utiliser include: serve est suffisant :

    • Par défaut, le nom de la page générée est test_ides.
    • Elle apparaît à la fin du menu de navigation, dans la documentation.
    • Toutes les fonctionnalités sont actives, comme décrites ci-dessus.


  • Pour générer la page sur le site construit via un pipeline, utiliser include: site. La page est alors rendue moins facilement accessible et ne comporte pas toutes les fonctionnalités, du fait que le site est public :

    • Le nom de la page générée reste test_ides, par défaut.
    • Elle existe sur le site, mais n'est pas ajoutée au menu de navigation : il faut donc rentrer l'adresse à la main dans le navigateur pour y accéder.
    • Les boutons de chargement des codes dans l'IDE de la page sont absents : download.
      En effet, cela rendrait visible publiquement l'intégralité des codes de tous les IDEs pour toute personne ayant connaissance de l'existence de la page de tests.
      Il est possible de modifier ce comportement si besoin (option testing.load_buttons: true), mais il ne faut alors pas oublier de désactiver l'option par la suite.


Les options présentes dans la sous-configuration testing du plugin sont décrites ci-dessous.

page = C.Type(str, default='test_ides')#

Nom de fichier markdown (avec ou sans l'extension .md) utilisé pour générer une page contenant le nécessaire pour tester de manière semi-automatisée tous les IDEs de la documentation.

  • La page n'est créée que si l'option testing.include n'est pas à null.
  • Une erreur est levée si un fichier du même nom existe déjà.
  • Une erreur est levée si le fichier n'est pas à la racine de la documentation.

include = C.Choice(('null', 'serve', 'site'), default='null')#

Définit si la page de tests des IDEs doit être générée et de quelle façon.

  • 'null' : la page de tests n'est pas générée.
  • 'serve' : la page de tests est générée pendant mkdocs serve, et est ajoutée automatiquement à la navigation.
  • 'site' : la page de tests est ajoutée sur le site construit, mais n'apparaît pas dans la navigation.

load_buttons = C.Optional(C.Type(bool))#

Définit si le bouton pour charger l'ensemble des codes associés à un IDE de la page des tests sera présent ou non.
Le comportement par défaut dépend de la valeur de l'option testing.include :

  • Pour testing.include: serve, le bouton est présent par défaut.
  • Pour testing.include: site, le bouton est absent par défaut.

empty_section_fallback = C.Choice(('', 'skip', 'fail', 'code', 'human', 'no_clear'), default='skip')#

Lorsque la page des tests des IDEs est construite et que la section à tester pour un IDE donné ne contient pas de code et que empty_section_fallback est définie, c'est cette "stratégie" qui sera utilisée à la place.

...du test d'un IDE#

Il est possible de modifier légèrement les comportements utilisés pour tester un IDE, en mettant à profit l'argument TEST des macros IDE et IDEv.
Les valeurs utilisables pour cet argument sont un peu particulières :

  • La valeur à utiliser est une des chaînes de caractères suivantes, quand utilisée via les données de configuration (mkdocs.yml, .meta.pmt.yml, ou les entêtes de pages markdown) :

    Valeur Effet
    "" (Défaut) Le test est fait avec la configuration par défaut...
    "skip" L'IDE ne sera pas testé.
    "fail" Si une erreur est levée, l'IDE sera considéré comme passant le test.
    (L'icône utilisée sera alors ).
    "code" C'est la section code qui sera testée, et non la section corr.
    "human" Marque le test comme nécessitant une intervention humaine (typiquement, up-/download). Par défaut, ces tests sont désactivés, mais un bouton dans l'interface permet de basculer l'état de ces tests spécifiquement.
    "no_clear" Dans ce cas, l'environnement pyodide n'est pas nettoyé au début du test.
    (Ceci peut s'avérer utile pour des exercices où plusieurs IDEs partagent des fonctions, variables ou objets et sont sensés être exécutés dans l'ordre)
  • Pour l'argument TEST des macros IDE et IDEv, on peut utiliser :

    • Les chaînes décrites ci-dessus, ...
    • ...mais il est également possible d'instancier des objets Case, qui vont permettre de combiner plusieurs paramètres (il est également possible d'ajouter une description au test) :

      Case(
          skip: bool = False,
          fail: bool = False,
          code: bool = False,
          human: bool = False,
          no_clear: bool = False,
          term_cmd: str="",
          description: str="",
      )
      


      La classe Case est disponible dans l'environnement des macros, ce qui permet de l'utiliser à l'intérieur même de l'appel à une macro :
      ... {{ IDE("exo", TEST=Case(no_clear=True, code=True)) }}



      Si l'argument term_cmd est utilisé, le test est effectué en lançant la commande en question dans le terminal. Noter que dans ce cas :

      • Les différentes sections sont exécutées exactement de la même façon que lors des exécutions normales (notamment, les sections env et post peuvent être exécutées ou non, selon qu'elles l'ont déjà été auparavant ou pas).
      • Il est possible d'utiliser des commandes multilignes.
      • Si l'objet Case utilise code=True, cet argument est ignoré et seule la commande indiquée avec l'argument term_cmd est exécutée.