Skip to Content

Chapitre 11.1 — QTI : échanger des tests

⏱️ TL;DRQTI (Question & Test Interoperability, 1EdTech) est le standard qui rend tes questions et tes tests portables entre plateformes : au lieu de recréer un QCM à la main dans chaque LMS, tu l’exportes une fois et il s’importe partout. L’unité de base est l’assessmentItem (une question) : un itemBody (l’énoncé + une interaction comme choiceInteraction ou textEntryInteraction), une responseDeclaration (la bonne réponse), une responseProcessing (comment noter), une outcomeDeclaration (le score produit). On regroupe des items dans un assessmentTest. Deux versions vivantes : QTI 2.1 (verbeux, éprouvé) et QTI 3.0 (2022, alignée HTML5, éléments préfixés qti-). QTI vit rarement seul : il voyage dans un Common Cartridge ou s’importe dans la banque de questions d’un LMS.

🎯 Objectifs

  • Expliquer à quoi sert QTI et pourquoi un QCM « portable » vaut mieux qu’un QCM ressaisi partout.
  • Lire et écrire un assessmentItem : itemBody, interaction, responseDeclaration, outcomeDeclaration, responseProcessing.
  • Nommer les interactions courantes (choiceInteraction, textEntryInteraction, matchInteraction…).
  • Comprendre le rôle de la responseProcessing (template match_correct vs logique sur mesure).
  • Distinguer QTI 2.1 et QTI 3.0, et savoir où vit un paquet QTI (Common Cartridge, LMS).

À quoi sert QTI

Tu as construit un test dans ton studio : dix questions, des QCM, des trous à remplir, une notation par question. Une école veut ce test dans son Moodle, une autre dans son Canvas, une troisième dans un outil maison. Sans standard, c’est trois ressaisies — et chaque correction de coquille est à refaire trois fois. QTI supprime ce mur : tu exportes le test une fois, au format QTI, et chaque plateforme conforme sait l’importer.

QTI décrit le contenu pédagogique d’une évaluation : l’énoncé, les choix, la bonne réponse, le barème, les retours (feedback). Il ne décrit ni l’apparence exacte (c’est le LMS qui met en page), ni le suivi de l’apprenant dans le temps (ça, c’est SCORM/xAPI/Caliper). QTI, c’est la question elle-même, rendue transportable.

💡 Réflexe — Sépare bien trois plans qu’on confond souvent : QTI = le contenu d’un test (questions, réponses, barème) ; AGS / OneRoster = la note qui en ressort et où elle atterrit ; SCORM / xAPI / Caliper = la trace de ce qu’a fait l’apprenant. Un même quiz peut être décrit en QTI, sa note renvoyée par AGS, et son passage tracé en xAPI. Trois standards, trois rôles.

L’assessmentItem : anatomie d’une question

Une question QTI, c’est quatre briques qui se répondent :

BriqueRôleÉlément
Le corpsL’énoncé + l’interaction que voit l’apprenantitemBody (+ choiceInteraction, etc.)
La bonne réponseCe qui est attenduresponseDeclaration (+ correctResponse)
La notationComment transformer la réponse en scoreresponseProcessing
Le résultatLa ou les variables produites (score…)outcomeDeclaration

Voici un QCM complet en QTI 2.1. Lis-le de haut en bas : chaque bloc correspond à une ligne du tableau.

<?xml version="1.0" encoding="UTF-8"?> <assessmentItem xmlns="http://www.imsglobal.org/xsd/imsqti_v2p1" identifier="choice-capitale-fr" title="Capitale de la France" adaptive="false" timeDependent="false"> <!-- Ce qui est attendu : la variable RESPONSE vaut ChoiceB --> <responseDeclaration identifier="RESPONSE" cardinality="single" baseType="identifier"> <correctResponse> <value>ChoiceB</value> </correctResponse> </responseDeclaration> <!-- Le résultat produit : une variable SCORE (float), 0 par défaut --> <outcomeDeclaration identifier="SCORE" cardinality="single" baseType="float"> <defaultValue> <value>0</value> </defaultValue> </outcomeDeclaration> <!-- Ce que voit l'apprenant : l'énoncé + l'interaction --> <itemBody> <p>Quelle est la capitale de la France ?</p> <choiceInteraction responseIdentifier="RESPONSE" shuffle="true" maxChoices="1"> <simpleChoice identifier="ChoiceA">Lyon</simpleChoice> <simpleChoice identifier="ChoiceB">Paris</simpleChoice> <simpleChoice identifier="ChoiceC">Marseille</simpleChoice> </choiceInteraction> </itemBody> <!-- Comment noter : template standard "réponse juste = 1, sinon 0" --> <responseProcessing template="http://www.imsglobal.org/question/qti_v2p1/rptemplates/match_correct"/> </assessmentItem>

Décryptage des rouages :

  • identifier / title : l’ID machine et le titre humain de l’item. L’identifier est la clé référencée par un assessmentTest.
  • responseDeclaration relie le nom de la variable de réponse (RESPONSE, réutilisé par l’interaction via responseIdentifier) à la bonne réponse (correctResponseChoiceB). Sa cardinality dit si on attend une valeur (single), plusieurs (multiple), ordonnée (ordered) ; son baseType dit le type (identifier, string, integer, float…).
  • outcomeDeclaration déclare la variable produite — ici SCORE. C’est elle que le LMS lira pour connaître le résultat.
  • itemBody contient un sous-ensemble de HTML (p, img, tableaux…) plus l’interaction. Ici choiceInteraction (un QCM) avec maxChoices="1" (une seule réponse) et shuffle="true" (choix mélangés).
  • responseProcessing est la logique de notation. Ici on invoque un template standard, match_correct : « si RESPONSE égale correctResponse, SCORE = 1, sinon 0 ». Pas besoin de la réécrire : QTI fournit des templates prêts.

⚠️ Piège — Croire que simpleChoice porte « la bonne réponse ». Non : les simpleChoice ne sont que les options affichées. La bonne réponse vit ailleurs, dans correctResponse (ChoiceB), reliée par l’identifier du choix. Séparer l’énoncé (itemBody) de la clé de correction (responseDeclaration) est voulu : ça permet de mélanger les choix (shuffle) sans jamais trahir la réponse, et de livrer une version « sans corrigé » si besoin.

Les interactions : au-delà du QCM

Le choiceInteraction n’est qu’une des interactions QTI. Chacune correspond à un type de question :

InteractionType de questionExemple
choiceInteractionQCM (choix unique ou multiple)« Quelle est la capitale… »
textEntryInteractionTrou à remplir, réponse courte« 2 + 2 = ___ »
extendedTextInteractionRéponse longue (rédaction)« Explique en 5 lignes… »
matchInteractionAppariement (relier A à B)Pays ↔ capitales
orderInteractionRemise en ordreTrier des étapes
inlineChoiceInteractionMenu déroulant dans le texte« La photosynthèse produit du [▾] »
hotspotInteractionZone à cliquer sur une imagePointer un organe

Un trou à remplir avec textEntryInteraction a une particularité : l’interaction est dans le texte, et la notation se fait souvent sur une chaîne (baseType="string"), parfois avec une table de correspondance pour accepter des variantes (« Paris », « paris », « PARIS »).

<responseDeclaration identifier="RESPONSE" cardinality="single" baseType="string"> <correctResponse> <value>Paris</value> </correctResponse> <mapping defaultValue="0"> <mapEntry mapKey="Paris" mappedValue="1"/> <mapEntry mapKey="paris" mappedValue="1"/> </mapping> </responseDeclaration> <itemBody> <p>La capitale de la France est <textEntryInteraction responseIdentifier="RESPONSE" expectedLength="15"/>.</p> </itemBody>

Ici la notation utilisera le template map_response (au lieu de match_correct) : il lit la mapping et attribue le mappedValue correspondant à la saisie. C’est le mécanisme du crédit partiel et de la tolérance orthographique.

responseProcessing : la logique de notation

La responseProcessing transforme la réponse de l’apprenant en outcome (le SCORE). Deux voies :

  1. Un template standard — le plus courant. match_correct (juste/faux) ou map_response (barème par une mapping). Une seule ligne, rien à écrire.
  2. Une logique sur mesure — quand le barème est particulier (points négatifs, conditions croisées). On l’écrit avec responseCondition / responseIf / setOutcomeValue :
<responseProcessing> <responseCondition> <responseIf> <match> <variable identifier="RESPONSE"/> <correct identifier="RESPONSE"/> </match> <setOutcomeValue identifier="SCORE"> <baseValue baseType="float">2</baseValue> </setOutcomeValue> </responseIf> <responseElse> <setOutcomeValue identifier="SCORE"> <baseValue baseType="float">-0.5</baseValue> </setOutcomeValue> </responseElse> </responseCondition> </responseProcessing>

Ici : bonne réponse → SCORE = 2 ; mauvaise → SCORE = -0,5 (malus). C’est le même modèle mental qu’un if/else, en XML.

💡 Réflexe — N’écris une responseProcessing sur mesure que si un template ne suffit pas. 90 % des questions se notent avec match_correct (juste/faux) ou map_response (barème). Réserver le sur-mesure aux cas réels (malus, seuils) garde tes items lisibles et portables : un template standard est compris par tous les moteurs QTI, une logique exotique l’est parfois moins.

De la question au test : assessmentTest

Un assessmentItem, c’est une question. Un assessmentTest organise plusieurs items en une épreuve : sections, ordre, temps imparti, mode de navigation, et agrégation des scores.

<assessmentTest identifier="test-geo-6e" title="Évaluation géographie 6e"> <testPart identifier="part1" navigationMode="linear" submissionMode="individual"> <assessmentSection identifier="sec1" title="Capitales" visible="true"> <assessmentItemRef identifier="q1" href="items/choice-capitale-fr.xml"/> <assessmentItemRef identifier="q2" href="items/textentry-capitale.xml"/> </assessmentSection> </testPart> <outcomeProcessing> <!-- somme des SCORE de chaque item -> SCORE total du test --> </outcomeProcessing> </assessmentTest>

Points-clés :

  • Le test ne recopie pas les questions : il les référence par assessmentItemRef (href vers le fichier de l’item). Une question réutilisable vit dans un seul fichier.
  • navigationMode (linear = on avance sans revenir en arrière ; nonlinear = navigation libre) et submissionMode (individual = correction question par question ; simultaneous = tout à la fin) définissent l’expérience.
  • outcomeProcessing agrège les scores des items en un score de test (souvent une somme).

QTI 2.1 vs QTI 3.0

Les deux versions décrivent la même chose ; elles diffèrent surtout par la syntaxe.

QTI 2.1QTI 3.0 (2022)
Nommage des élémentscamelCase : assessmentItem, choiceInteractionkebab-case préfixé : qti-assessment-item, qti-choice-interaction
AttributstimeDependent, maxChoicestime-dependent, max-choices
AlignementXML « historique »Aligné HTML5 / web (intégration front plus naturelle)
Accessibilité, stylesSupport de baseRenforcé (PNP, partage avec APIP)
Namespaceimsqti_v2p1imsqtiasi_v3p0

Le même QCM en QTI 3.0 :

<?xml version="1.0" encoding="UTF-8"?> <qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" identifier="choice-capitale-fr" title="Capitale de la France" adaptive="false" time-dependent="false"> <qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="identifier"> <qti-correct-response> <qti-value>ChoiceB</qti-value> </qti-correct-response> </qti-response-declaration> <qti-outcome-declaration identifier="SCORE" cardinality="single" base-type="float"> <qti-default-value> <qti-value>0</qti-value> </qti-default-value> </qti-outcome-declaration> <qti-item-body> <p>Quelle est la capitale de la France ?</p> <qti-choice-interaction response-identifier="RESPONSE" shuffle="true" max-choices="1"> <qti-simple-choice identifier="ChoiceA">Lyon</qti-simple-choice> <qti-simple-choice identifier="ChoiceB">Paris</qti-simple-choice> <qti-simple-choice identifier="ChoiceC">Marseille</qti-simple-choice> </qti-choice-interaction> </qti-item-body> <!-- template standard match_correct ; URI réalignée en v3, voir 1edtech.org --> <qti-response-processing template="match_correct"/> </qti-assessment-item>

Même structure, même logique — seuls les noms changent. Qui comprend l’un comprend l’autre.

⚠️ Piège — Exporter en QTI 3.0 vers un LMS qui n’importe encore que QTI 2.1 (ou pire, une variante maison). Le support QTI varie beaucoup d’une plateforme à l’autre : certains n’ingèrent qu’un sous-ensemble, d’autres passent par leur propre format de banque de questions. Ne suppose jamais qu’« exporter en QTI » suffit : teste l’import réel sur le LMS cible, et garde sous la main une version 2.1 tant que le 3.0 n’est pas partout accepté.

Où vit un paquet QTI

QTI se transporte rarement « à nu ». On le rencontre :

  • Dans un content package dédié : un .zip avec un imsmanifest.xml qui liste les items et tests (même idée de manifeste que SCORM, Partie 3).
  • Dans un Common Cartridge : le paquet de cours (chapitre suivant, 11.2) embarque volontiers ses tests au format QTI, aux côtés des ressources et des liens LTI.
  • Importé dans un LMS : Moodle, Canvas et consorts savent (plus ou moins complètement) importer du QTI dans leur banque de questions, où les items deviennent réutilisables dans des quiz natifs.

🔌 Côté intégration — Pour un éditeur de contenu, exporter du QTI propre est un argument commercial : l’école n’est pas « prisonnière » de ton lecteur, elle récupère ses questions dans son LMS. Mais l’inverse t’engage : si tu vends un LMS, savoir importer du QTI (et pas juste ton format maison) élargit ton catalogue aux banques de questions du marché. 1EdTech certifie la conformité QTI ; le label rassure les acheteurs institutionnels échaudés par les imports ratés.

🧭 Sur FormaCampus — Le studio d’exercices de FormaCampus (celui qu’on a branché en outil LTI, Partie 10) sait aussi exporter ses tests en QTI. Une académie cliente ne veut pas d’un outil externe pour ses évaluations bac blanc : elle veut les questions dans son Moodle. FormaCampus génère un paquet QTI 2.1 (le plus sûr pour l’import Moodle), l’académie l’importe dans sa banque de questions, et compose ses propres quiz. Bonus : FormaCampus importe aussi du QTI, ce qui lui permet d’ingérer des banques de questions déjà produites par les enseignants. QTI dans les deux sens : import et export.

📚 La spec — QTI (Question & Test Interoperability) est publié par 1EdTech (1edtech.org). Concepts stables : assessmentItem (itemBody, interactions, responseDeclaration, responseProcessing, outcomeDeclaration) et assessmentTest (testPart, assessmentSection, assessmentItemRef, outcomeProcessing). Versions 2.1 puis 3.0 (2022, alignée HTML5, éléments qti-…, namespace imsqtiasi_v3p0). Les templates de responseProcessing (match_correct, map_response) et leurs URI exactes sont sur 1edtech.org. QTI est souvent voisin d’APIP (accessibilité) ; ne pas confondre QTI (le contenu du test) avec le suivi de l’apprenant (SCORM/xAPI/Caliper).

✏️ Exercices

Exercice 1 — Lis l’item. On te donne cet extrait. Que vaut la bonne réponse, combien de choix l’apprenant peut-il cocher, et quel score obtient-il s’il répond juste ?

<responseDeclaration identifier="RESPONSE" cardinality="multiple" baseType="identifier"> <correctResponse> <value>A</value> <value>C</value> </correctResponse> </responseDeclaration> <outcomeDeclaration identifier="SCORE" cardinality="single" baseType="float"> <defaultValue><value>0</value></defaultValue> </outcomeDeclaration> <itemBody> <choiceInteraction responseIdentifier="RESPONSE" maxChoices="2"> <simpleChoice identifier="A">Réponse A</simpleChoice> <simpleChoice identifier="B">Réponse B</simpleChoice> <simpleChoice identifier="C">Réponse C</simpleChoice> </choiceInteraction> </itemBody> <responseProcessing template="http://www.imsglobal.org/question/qti_v2p1/rptemplates/match_correct"/>

✅ Solution

C’est un QCM à choix multiple (cardinality="multiple", maxChoices="2"). La bonne réponse est A et C (les deux value de correctResponse). L’apprenant peut cocher jusqu’à 2 choix. Avec le template match_correct, il obtient SCORE = 1 uniquement s’il coche exactement A et C (ni plus, ni moins) ; toute autre combinaison donne 0. match_correct est tout ou rien : pour du crédit partiel, il faudrait map_response avec une mapping.

Exercice 2 — Écris la question. Rédige un assessmentItem QTI 2.1 pour : « En quelle année a été signé le traité de Rome ? », réponse attendue 1957, saisie libre, notée 1 point si juste. Indique l’interaction et le template.

✅ Solution

Une saisie libretextEntryInteraction, réponse de type string, notation par map_response (ou match_correct si une seule graphie suffit) :

<responseDeclaration identifier="RESPONSE" cardinality="single" baseType="string"> <correctResponse><value>1957</value></correctResponse> <mapping defaultValue="0"> <mapEntry mapKey="1957" mappedValue="1"/> </mapping> </responseDeclaration> <outcomeDeclaration identifier="SCORE" cardinality="single" baseType="float"> <defaultValue><value>0</value></defaultValue> </outcomeDeclaration> <itemBody> <p>En quelle année a été signé le traité de Rome ? <textEntryInteraction responseIdentifier="RESPONSE" expectedLength="4"/></p> </itemBody> <responseProcessing template="http://www.imsglobal.org/question/qti_v2p1/rptemplates/map_response"/>

L’interaction est dans la phrase (textEntryInteraction). Le template map_response lit la mapping : 1957 → 1 point, tout le reste → 0.

Exercice 3 — 2.1 ou 3.0 ? Une école cible utilise un vieux Moodle qui « importe du QTI », mais tu ne sais pas quelle version. Ton studio peut exporter en 2.1 ou 3.0. Que fais-tu ?

✅ Solution

Tu testes l’import réel sur une instance de la cible avant de livrer, et par défaut tu exportes en QTI 2.1 : c’est la version la plus largement supportée par les LMS existants, notamment les Moodle plus anciens. QTI 3.0 est plus moderne (aligné HTML5) mais son support d’import est inégal. Règle : ne jamais présumer qu’« exporter en QTI » suffit — la version et le sous-ensemble supporté varient. En cas de doute, 2.1 + test d’import réel.

🧠 Quiz de révision

1. Quelles sont les quatre briques d’un assessmentItem ?

itemBody (l’énoncé + l’interaction), responseDeclaration (la bonne réponse attendue), responseProcessing (la logique de notation), outcomeDeclaration (la variable produite, souvent SCORE). L’énoncé et la clé de correction sont volontairement séparés.

2. Où se trouve la bonne réponse d’un QCM QTI ?

Dans la responseDeclaration, à l’intérieur de correctResponse (value → l’identifier du bon simpleChoice). Pas dans les simpleChoice eux-mêmes, qui ne sont que les options affichées. Cette séparation permet de mélanger les choix (shuffle) sans trahir la réponse.

3. À quoi sert responseProcessing et quels templates standards existe-t-il ?

Elle transforme la réponse en score. Deux templates courants : match_correct (juste = 1, faux = 0, tout ou rien) et map_response (barème/crédit partiel via une mapping). On peut aussi écrire une logique sur mesure (responseCondition/responseIf/setOutcomeValue) pour des cas particuliers (malus, seuils).

4. Quelle différence principale entre QTI 2.1 et QTI 3.0 ?

Surtout la syntaxe : QTI 2.1 en camelCase (assessmentItem, choiceInteraction) ; QTI 3.0 (2022) en kebab-case préfixé qti- (qti-assessment-item, qti-choice-interaction), avec attributs en kebab-case (max-choices) et un alignement HTML5. Le modèle conceptuel est le même.

5. Où vit concrètement un paquet QTI ?

Dans un content package dédié (.zip + imsmanifest.xml), dans un Common Cartridge (aux côtés des ressources et liens LTI), ou importé dans la banque de questions d’un LMS. Le support d’import varie selon la plateforme : toujours tester l’import réel.


Chapitre suivant : 11.2 — Common Cartridge — le paquet qui transporte un cours entier, tests QTI et liens LTI compris.

Last updated on