Tester une règle XSLT isolée, sans jouer toute la feuille
Rejouer une transformation entière pour vérifier une règle rend le diagnostic long et le test fragile. Un modèle nommé s'appelle directement.
Rejouer une transformation entière pour vérifier une règle coûte cher deux fois : à l'exécution, et surtout à la lecture, parce que l'échec peut venir de n'importe où dans la chaîne.
Un modèle nommé s'appelle directement. Le test devient court, rapide, et il n'échoue que pour une raison — à condition de savoir ce que l'isolement vient de retirer du test.
Appeler le modèle, pas la feuille
<x:scenario label="le formatage d'un montant">
<x:call template="formater-montant">
<x:param name="valeur" select="1234.5"/>
</x:call>
<x:expect label="deux décimales">1 234,50</x:expect>
</x:scenario>
Le test ne dépend plus du document d'entrée, ni de l'ordre d'application des modèles. La lecture du rapport prend quelques secondes au lieu de quelques minutes.
Ce que l'isolement retire du test
Une transformation fait deux choses, et elles échouent séparément :
| Ce qui est fait | Ce qui casse | Ce qu'un appel direct en dit |
|---|---|---|
| choisir le modèle qui s'applique | match trop étroit, espace de noms, priorité | rien |
| calculer ce qu'il produit | une expression fausse, un arrondi | tout |
🔴 L'appel direct teste le calcul et supprime la sélection. Or la sélection est la moitié qui
casse le plus souvent : un match qui ne prend rien laisse le modèle parfaitement correct et la
sortie parfaitement vide. C'est le symptôme décrit dans
les cinq causes silencieuses d'un XSLT vide, et aucun test
isolé ne le verra jamais — pas parce qu'il est mal écrit, parce qu'il ne regarde pas là.
D'où la règle : isoler pour tester le calcul, garder un scénario de bout en bout pour tester la sélection. Un seul scénario complet suffit ; c'est son absence qui coûte.
Les modèles qui n'ont pas de nom
La plupart des modèles se déclarent avec match, pas avec name. On ne les appelle pas — on leur
présente un nœud, dans un mode :
<xsl:template match="ligne" mode="montant">
<xsl:value-of select="format-number(@prix * @quantite, '# ##0,00')"/>
</xsl:template>
Le mode est ce qui rend l'isolement possible sans appel direct : il restreint les modèles candidats à ceux qui le déclarent.
<x:scenario label="une ligne de montant">
<x:context mode="montant">
<ligne prix="12.5" quantite="4"/>
</x:context>
<x:expect label="le produit formaté">50,00</x:expect>
</x:scenario>
✅ Ici la sélection est testée, dans un périmètre restreint. C'est le compromis le plus utile des trois : le test reste court, et la moitié qui casse le plus souvent reste couverte.
Trois pièges de l'appel direct
⚠️ Il n'y a pas de nœud courant. Un modèle qui lit ., .. ou un chemin relatif n'a rien à
quoi se rattacher : le processeur lève une erreur de contexte, et c'est le bon cas. Le mauvais
cas est le modèle qui ne lit . que dans une branche rarement prise — le test passe des mois, et
la branche tombe en production.
⚠️ Les valeurs par défaut des paramètres masquent les appels réels. Un x:call qui omet un
xsl:param prend sa valeur par défaut. Le test passe, la production échoue, et l'écart est un
paramètre que personne n'a écrit nulle part.
⚠️ Les variables globales, elles, sont bien évaluées. Une variable globale qui lit le document source est vide, ou en erreur, pendant l'appel isolé, alors qu'elle a une valeur en production. Ses causes de vacuité sont celles de toute variable XSLT vide, et elles se lisent de la même façon.
Ce que cet article ne couvre pas
- les fonctions
xsl:function, qui s'appellent avecx:call functionet n'ont jamais de contexte — le premier piège ne les concerne pas ; - les paquets XSLT 3.0 et leurs composants privés, qui ne sont pas visibles de l'extérieur ;
- la mise en place de l'outil, décrite dans XSpec en pratique.
Quand un test isolé passe et que la feuille échoue, la différence est toujours un contexte : le chapitre déboguer du manuel montre comment l'observer au moment de l'appel.