Tester · Publié le

XSpec en pratique : tester une feuille XSLT

XSpec décrit ce qu'une feuille de style doit produire, dans un fichier XML séparé. Le premier test utile tient en quinze lignes.

XSpec décrit ce qu'une feuille de style doit produire, dans un fichier XML séparé qui ne touche pas au code testé. C'est ce qui permet de le tenir à jour : un test écrit dans la feuille disparaît à la première refonte, et personne ne s'en aperçoit.

Le premier test utile tient en quinze lignes. La moitié du travail consiste ensuite à savoir ce que « il passe » veut dire exactement.

Le premier test

XML
<x:description stylesheet="facture.xsl"
               xmlns:x="http://www.jenitennison.com/xslt/xspec">
  <x:scenario label="une facture sans ligne">
    <x:context>
      <facture/>
    </x:context>
    <x:expect label="produit un total à zéro">
      <total>0</total>
    </x:expect>
  </x:scenario>
</x:description>

x:context fournit le document d'entrée, x:expect décrit le résultat attendu. Le scénario échoue si les deux arbres diffèrent.

« Les deux arbres », et pas « les deux fichiers »

🔴 La comparaison porte sur l'arbre du résultat, avant sérialisation. Rien de ce qui se décide au moment d'écrire les octets n'est vu : ni l'encodage, ni la déclaration XML, ni l'indentation. Une feuille dont la sortie s'ouvre en caractères illisibles passe la suite XSpec au vert — ces causes-là sont du côté de la sérialisation, et le test ne traverse pas cette étape.

⚠️ Les nœuds de texte, en revanche, sont dans l'arbre. Un x:expect réindenté pour rester lisible introduit des blancs que le résultat n'a pas, et le scénario échoue sur une différence qui ne se voit pas dans le rapport. C'est le mécanisme décrit dans les espaces blancs en XSLT, appliqué cette fois au fichier de test lui-même.

Pour ne comparer qu'une partie du résultat, select évalue une expression sur ce qui a été produit :

XML
<x:expect label="le total seul" select="/facture/total" test="xs:integer(.) eq 0"/>

⚠️ L'inversion classique est de croire que ce select porte sur le contexte d'entrée. Il porte sur la sortie.

Les scénarios s'emboîtent

Un scénario imbriqué hérite du x:context de son parent, ce qui évite de recopier l'entrée pour chaque assertion :

XML
<x:scenario label="une facture à deux lignes">
  <x:context href="facture.xml"/>
  <x:scenario label="le total"><x:expect select="/facture/total"/></x:scenario>
  <x:scenario label="le nombre de lignes"><x:expect select="count(//ligne)"/></x:scenario>
</x:scenario>

⚠️ Un enfant qui redéclare x:context remplace celui du parent, il ne le complète pas. Et un href relatif se résout par rapport au fichier .xspec, jamais par rapport au répertoire d'où la commande est lancée.

Trois façons de passer sans rien vérifier

🔴 Un test vert n'est une information que si le rouge était possible. Trois cas rendent exactement le signal attendu sans avoir rien mesuré :

Le casCe que le rapport affiche
scénario sans x:expectsuccès, zéro assertion
scénario marqué pendingignoré, compté à part
focus posé sur un autre scénarioles autres ne sont pas joués

Les deux derniers sont signalés dans le rapport HTML — encore faut-il l'ouvrir. ⚠️ Un pending posé pour une après-midi et oublié se comporte comme un test réussi pour qui ne lit que la couleur d'ensemble.

Ce qu'un test vert ne dit pas

  • il ne dit rien des performances : la même sortie en dix secondes ou en dix minutes passe pareil ;
  • il ne dit rien du fichier produit, seulement de l'arbre ;
  • il ne dit rien des entrées que vous n'avez pas écrites, et c'est la limite de tout test par l'exemple.

Pour un premier essai, il est plus rapide d'isoler une règle que de jouer la feuille entière : voir tester une règle XSLT isolée.

Ce que cet article ne couvre pas

  • les tests de fonctions et de paquets XSLT 3.0, qui ont leur propre syntaxe d'appel ;
  • l'exécution en intégration continue, où le code de sortie compte plus que le rapport ;
  • les schémas : XSpec vérifie un résultat attendu, jamais une validité.

Le chapitre valider et comparer du manuel décrit la comparaison d'arbres sur laquelle repose la vérification.

Sur le même sujet

Recevoir les nouveaux articles

Un message quand un article paraît. Rien d'autre : ni promotion, ni relance, ni lettre d'information.

Votre adresse ne sert qu'à cela et n'est transmise à personne. Un lien de désinscription accompagne chaque message. Confidentialité

Tous les articles