Sur cette page

Qt Test Vue d'ensemble

Qt Test est un cadre de test unitaire pour les applications et les bibliothèques basées sur Qt Test. Qt Test fournit toutes les fonctionnalités que l'on trouve habituellement dans les cadres de test unitaire ainsi que des extensions pour tester les interfaces utilisateur graphiques.

Qt Test est conçu pour faciliter l'écriture de tests unitaires pour les applications et les bibliothèques basées sur Qt :

FonctionnalitéDétails
LégerQt Test consiste en environ 6000 lignes de code et 60 symboles exportés.
AutonomeQt Test ne nécessite que quelques symboles du module Qt Core pour les tests non-gui.
Tests rapidesQt Test ne nécessite pas de programme d'exécution de test spécial ; pas d'enregistrement spécial pour les tests.
Tests guidés par les donnéesUn test peut être exécuté plusieurs fois avec des données de test différentes.
Les tests d'interface graphique de baseQt Test offre une fonctionnalité de simulation de la souris et du clavier.
Analyse comparativeQt Test prend en charge l'analyse comparative et fournit plusieurs backends de mesure.
Convivialité de l'IDEQt Test produit des messages qui peuvent être interprétés par Qt Creator, Visual Studio et KDevelop.
Sécurité des threadsLe rapport d'erreur est sûr pour les threads et atomique.
Sécurité de typeL'utilisation extensive de modèles permet d'éviter les erreurs introduites par le moulage implicite des types.
Facilement extensibleDes types personnalisés peuvent être facilement ajoutés aux données et aux résultats des tests.

Vous pouvez utiliser un assistant Qt Creator pour créer un projet contenant des Qt Test et les construire et les exécuter directement à partir de Qt Creator. Pour plus d'informations, voir Qt Creator: Build and run tests.

Création d'un test

Pour créer un test, sous-classez QObject et ajoutez-y un ou plusieurs emplacements privés. Chaque slot privé est une fonction de test dans votre test. QTest::qExec() peut être utilisé pour exécuter toutes les fonctions de test de l'objet test.

En outre, vous pouvez définir les emplacements privés suivants qui ne sont pas traités comme des fonctions de test. Lorsqu'ils sont présents, ils sont exécutés par le cadre de test et peuvent être utilisés pour initialiser et nettoyer le test entier ou la fonction de test actuelle.

  • initTestCase() sera appelé avant l'exécution de la première fonction de test.
  • initTestCase_data() sera appelée pour créer une table de données de test globale.
  • cleanupTestCase() sera appelée après l'exécution de la dernière fonction de test.
  • init() sera appelé avant l'exécution de chaque fonction de test.
  • cleanup() sera appelé après chaque fonction de test.

Utilisez initTestCase() pour préparer le test. Chaque test doit laisser le système dans un état utilisable, de sorte qu'il puisse être exécuté à plusieurs reprises. Les opérations de nettoyage doivent être gérées dans cleanupTestCase(), de sorte qu'elles soient exécutées même si le test échoue.

Utilisez init() pour préparer une fonction de test. Chaque fonction de test doit laisser le système dans un état utilisable, de sorte qu'elle puisse être exécutée à plusieurs reprises. Les opérations de nettoyage doivent être gérées dans cleanup(), de sorte qu'elles soient exécutées même si la fonction de test échoue et se termine prématurément.

Vous pouvez également utiliser RAII (resource acquisition is initialization), avec des opérations de nettoyage appelées dans les destructeurs, pour vous assurer qu'elles sont exécutées lorsque la fonction de test revient et que l'objet sort du champ d'application.

Si initTestCase() échoue, aucune fonction de test ne sera exécutée. Si init() échoue, la fonction de test suivante ne sera pas exécutée, le test passera à la fonction de test suivante.

Exemple :

class MyFirstTest : public QObject
{private: bool myCondition() { return true; }private slots: void initTestCase()    {
        qDebug("Called before everything else.");
    } void myFirstTest() { QVERIFY(true) ; // vérifie qu'une condition est remplieQCOMPARE(1, 1) ; // compare deux valeurs} void mySecondTest() { QVERIFY(myCondition()) ; QVERIFY(1 != 2) ; } void cleanupTestCase()    {
        qDebug("Called after myFirstTest and mySecondTest.");
    } } ;

Enfin, si la classe de test possède une méthode publique statique void initMain(), celle-ci est appelée par les macros QTEST_MAIN avant que l'objet QApplication ne soit instancié. Ceci a été ajouté dans la version 5.14.

Pour plus d'exemples, consultez le didacticielQt Test .

Augmentation du délai d'attente de la fonction de test

QtTest limite la durée d'exécution de chaque test afin de détecter les boucles infinies et les bogues similaires. Par défaut, tout appel à une fonction de test est interrompu au bout de cinq minutes. Pour les tests basés sur des données, ce délai s'applique à chaque appel avec une étiquette de données distincte. Ce délai peut être configuré en fixant la variable d'environnement QTEST_FUNCTION_TIMEOUT au nombre maximal de millisecondes acceptable pour un seul appel. Si un test dure plus longtemps que le délai configuré, il est interrompu et qFatal() est appelé. Par conséquent, le test s'interrompt par défaut, comme s'il s'était écrasé.

Pour définir QTEST_FUNCTION_TIMEOUT à partir de la ligne de commande sous Linux ou macOS, entrez :

QTEST_FUNCTION_TIMEOUT=900000
export QTEST_FUNCTION_TIMEOUT

Sous Windows :

SET QTEST_FUNCTION_TIMEOUT=900000

Exécutez ensuite le test dans cet environnement.

Vous pouvez également définir la variable d'environnement de manière programmatique dans le code du test lui-même, par exemple en appelant la méthode spéciale initMain() de votre classe de test :

qputenv("QTEST_FUNCTION_TIMEOUT", "900000");

Pour calculer une valeur appropriée pour le délai d'attente, observez la durée habituelle du test et déterminez combien de temps il peut durer sans que cela ne soit le symptôme d'un problème. Convertissez ce temps plus long en millisecondes pour obtenir la valeur du délai d'attente. Par exemple, si vous décidez qu'un test qui prend plusieurs minutes peut raisonnablement durer jusqu'à vingt minutes, par exemple sur une machine lente, multipliez 20 * 60 * 1000 = 1200000 et fixez la variable d'environnement à 1200000 au lieu de 900000 ci-dessus.

Construction d'un test

Vous pouvez créer un exécutable contenant une classe de test qui teste généralement une classe de code de production. Cependant, vous souhaitez généralement tester plusieurs classes d'un projet en exécutant une seule commande.

Voir Écrire un test d'unité pour une explication étape par étape.

Construire avec CMake et CTest

Vous pouvez utiliser CMake et CTest pour créer un test. CTest vous permet d'inclure ou d'exclure des tests sur la base d'une expression régulière qui est comparée au nom du test. Vous pouvez également appliquer la propriété LABELS à un test et CTest peut alors inclure ou exclure des tests sur la base de ces étiquettes. Toutes les cibles étiquetées seront exécutées lorsque test target est appelé sur la ligne de commande.

Remarque : sur Android, si vous avez un seul appareil ou émulateur connecté, les tests s'exécuteront sur cet appareil. Si vous avez plus d'un appareil connecté, définissez la variable d'environnement ANDROID_DEVICE_SERIAL avec le numéro de série ADB de l'appareil sur lequel vous souhaitez exécuter les tests.

CMake présente plusieurs autres avantages. Par exemple, le résultat d'un test peut être publié sur un serveur web à l'aide de CDash sans pratiquement aucun effort.

CTest s'adapte à des cadres de tests unitaires très différents et fonctionne d'emblée avec QTest.

Voici un exemple de fichier CMakeLists.txt qui spécifie le nom du projet et le langage utilisé (ici, mytest et C++), les modules Qt Test nécessaires à la construction du test (Qt Test) et les fichiers inclus dans le test(tst_mytest.cpp).

project(mytest LANGUAGES CXX)

find_package(Qt6 REQUIRED COMPONENTS Test)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOMOC ON)

enable_testing(true)

qt_add_executable(mytest tst_mytest.cpp)
add_test(NAME mytest COMMAND mytest)

target_link_libraries(mytest PRIVATE Qt::Test)

Pour plus d'informations sur les options disponibles, voir Construire avec CMake.

Construire avec qmake

Si vous utilisez qmake comme outil de construction, ajoutez simplement ce qui suit à votre fichier de projet :

QT += testlib

Si vous souhaitez exécuter le test via make check, ajoutez la ligne suivante :

CONFIG += testcase

Pour empêcher l'installation du test sur votre cible, ajoutez la ligne suivante :

CONFIG += no_testcase_installs

Voir le manuel qmake pour plus d'informations sur make check.

Construire avec d'autres outils

Si vous utilisez d'autres outils de construction, assurez-vous d'ajouter l'emplacement des fichiers d'en-tête Qt Test à votre chemin d'inclusion (habituellement include/QtTest sous votre répertoire d'installation de Qt). Si vous utilisez une version release de Qt Test, liez votre test à la bibliothèque QtTest. Pour les versions de débogage, utilisez QtTest_debug.

Qt Test Arguments de la ligne de commande

Syntaxe de la ligne de commande

La syntaxe d'exécution d'un autotest prend la forme simple suivante :

testname [options] [testfunctions[:testdata]]...

Remplacez testname par le nom de votre exécutable. testfunctions peut contenir les noms des fonctions de test à exécuter. Si aucun testfunctions n'est transmis, tous les tests sont exécutés. Si vous ajoutez le nom d'une entrée dans testdata, la fonction de test sera exécutée uniquement avec ces données de test.

Par exemple :

/myTestDirectory$ testQString toUpper

Exécute la fonction de test appelée toUpper avec toutes les données de test disponibles.

/myTestDirectory$ testQString toUpper toInt:zero

Exécute la fonction de test toUpper avec toutes les données de test disponibles et la fonction de test toInt avec la ligne de données de test appelée zero (si les données de test spécifiées n'existent pas, le test associé échoue et les balises de données disponibles sont signalées).

/myTestDirectory$ testMyWidget -vs -eventdelay 500

Exécute le test de la fonction testMyWidget, émet chaque émission de signal et attend 500 millisecondes après chaque événement simulé de la souris ou du clavier.

Options

Options d'enregistrement

Les options de ligne de commande suivantes déterminent la manière dont les résultats des tests sont consignés :

  • -o nom de fichier, format
    Writes output to the specified file, in the specified format (one of txt, csv, junitxml, xml, lightxml, teamcity or tap). Use the special filename - (hyphen) to log to standard output.
  • -o filename
    Enregistre les résultats dans le fichier spécifié
  • .-txt
    Affiche les résultats en texte brut.
  • -csv
    Affiche les résultats sous forme de valeurs séparées par des virgules (CSV), ce qui permet de les importer dans des feuilles de calcul. Ce mode n'est adapté qu'aux tests, car il supprime les messages normaux de réussite ou d'échec.
  • -junitxml
    Affiche les résultats sous la forme d'un document JUnit XML.
  • -xml
    Affiche les résultats sous la forme d'un document XML.
  • -lightxml
    Affiche les résultats sous la forme d'un flux de balises XML.
  • -teamcity
    Affiche les résultats au format TeamCity.
  • -tap
    Affiche les résultats au format Test Anything Protocol (TAP).

La première version de l'option -o peut être répétée afin d'enregistrer les résultats des tests dans plusieurs formats, mais pas plus d'une instance de cette option ne peut enregistrer les résultats des tests sur la sortie standard.

Si la première version de l'option -o est utilisée, ni la deuxième version de l'option -o ni les options -txt, -xml, -lightxml, -teamcity, -junitxml ou -tap ne doivent être utilisées.

Si aucune version de l'option -o n'est utilisée, les résultats des tests seront enregistrés sur la sortie standard. Si aucune option de format n'est utilisée, les résultats des tests seront enregistrés en texte brut.

Options de détail du journal des tests

Les options de ligne de commande suivantes permettent de contrôler le niveau de détail des journaux de test :

  • -silent
  • Sortie silencieuse ; ne montre que les erreurs fatales, les échecs des tests et les messages d'état minimaux.
  • -v1
    Sortie verbeuse ; montre quand chaque fonction de test est entrée. (Cette option n'affecte que la sortie en texte brut.)
  • -v2
    Extended verbose output; shows each QCOMPARE() and QVERIFY(). (This option affects all output formats and implies -v1 for plain text output.)
  • -vs
    Affiche tous les signaux émis et les invocations de slots résultant de ces signaux. (Cette option affecte tous les formats de sortie.)

Options de test

Les options de ligne de commande suivantes influencent l'exécution des tests :

  • -functions
  • Sort toutes les fonctions de test disponibles dans le test, puis quitte.
  • -datatags
    Sort toutes les balises de données disponibles dans le test. Une balise de données globale est précédée de ' __global__ '.
  • -eventdelay ms
    If no delay is specified for keyboard or mouse simulation (QTest::keyClick(), QTest::mouseClick() etc.), the value from this parameter (in milliseconds) is substituted.
  • -keydelay ms
    Comme -eventdelay, mais n'influence que la simulation du clavier et non celle de la souris.
  • -mousedelay ms
    Comme -eventdelay, mais n'influence que la simulation de la souris et non celle du clavier.
  • -maxwarnings number
    Définit le nombre maximum d'avertissements à émettre. 0 pour un nombre illimité, 2000 par défaut.
  • -nocrashhandler
    Désactive le gestionnaire de crash sur les plates-formes Unix. Sous Windows, il réactive la boîte de dialogue Windows Error Reporting, qui est désactivée par défaut. Cette fonction est utile pour déboguer les plantages.
  • -repeat n
    Exécute la suite de tests n fois ou jusqu'à ce que le test échoue. Utile pour repérer les tests défaillants. En cas d'échec, les tests sont répétés à l'infini. Il s'agit d'un outil destiné aux développeurs, qui n'est pris en charge qu'avec l'enregistreur de texte brut.
  • -skipblacklisted
    Ignorer les tests figurant sur la liste noire. Cette option est destinée à permettre une mesure plus précise de la couverture des tests en empêchant les tests de la liste noire de gonfler les statistiques de couverture. Lorsque la couverture des tests n'est pas mesurée, il est recommandé d'exécuter les tests de la liste noire pour révéler tout changement dans leurs résultats, comme un nouveau plantage ou la résolution du problème qui a causé la mise sur liste noire.
  • -platform name
    This command line argument applies to all Qt applications, but might be especially useful in the context of auto-testing. By using the "offscreen" platform plugin (-platform offscreen) it's possible to have tests that use QWidget or QWindow run without showing anything on the screen. Currently the offscreen platform plugin is only fully supported on X11.

Options d'étalonnage

Les options de ligne de commande suivantes permettent de contrôler les tests d'évaluation des performances :

  • -callgrind
    Utilise Callgrind pour chronométrer les tests (Linux et macOS).
  • -perf
    Utilise les événements perf de Linux pour chronométrer les points de repère
  • -tickcounter
    Utilise les compteurs de tic-tac de l'unité centrale pour chronométrer les points de référence. Nécessite la prise en charge du matériel.
  • -eventcounter
    Compte les événements reçus pendant les tests.
  • -minimumvalue n
    Définit la valeur de mesure minimale acceptable.
  • -minimumtotal n
    Définit le total minimum acceptable pour les exécutions répétées d'une fonction de test.
  • -iterations n
    Définit le nombre d'itérations d'accumulation.
  • -median n
    Définit le nombre d'itérations médianes.
  • -vb
    Affiche des informations verbales sur l'analyse comparative.

Options diverses

  • -help
    Affiche les arguments possibles de la ligne de commande et fournit une aide utile.

Qt Test Variables d'environnement

Vous pouvez définir certaines variables d'environnement afin d'affecter l'exécution d'un autotest :

  • QTEST_DISABLE_CORE_DUMP
    Définir cette variable à une valeur non nulle désactivera la génération d'un fichier core dump.
  • QTEST_DISABLE_STACK_DUMP
    Définir cette variable à une valeur non nulle empêchera Qt Test d'imprimer une trace de pile dans le cas où un autotest s'arrête ou se bloque.
  • QTEST_FATAL_FAIL
    En fixant cette variable à une valeur non nulle, un échec dans un autotest entraînera l'abandon immédiat de l'ensemble de l'autotest. Ceci est utile par exemple pour déboguer un échec instable ou intermittent dans un test, en lançant le test dans un débogueur. La prise en charge de cette variable a été ajoutée dans Qt 6.1.

Création d'un test de référence

Pour créer un test de référence, suivez les instructions de création d'un test, puis ajoutez une macro QBENCHMARK ou QTest::setBenchmarkResult() à la fonction de test que vous souhaitez comparer. Dans l'extrait de code suivant, la macro est utilisée :

class MyFirstBenchmark: public QObject
{
    Q_OBJECT
private slots:
    void myFirstBenchmark()
    {
        QString string1;
        QString string2;
        QBENCHMARK {
            string1.localeAwareCompare(string2);
        }
    }
};

Une fonction de test qui mesure les performances doit contenir une seule macro QBENCHMARK ou un seul appel à setBenchmarkResult(). Les occurrences multiples n'ont pas de sens, car un seul résultat de performance peut être rapporté par fonction de test, ou par balise de données dans une configuration axée sur les données.

Évitez de modifier le code de test qui forme (ou influence) le corps d'une macro QBENCHMARK ou le code de test qui calcule la valeur transmise à setBenchmarkResult(). Les différences dans les résultats de performance successifs ne devraient idéalement être causées que par des changements dans le produit que vous testez. Les modifications apportées au code de test peuvent potentiellement donner lieu à un rapport trompeur sur un changement de performance. Si vous devez modifier le code de test, indiquez-le clairement dans le message de validation.

Dans une fonction de test de performance, le code QBENCHMARK ou setBenchmarkResult() doit être suivi d'une étape de vérification à l'aide de QCOMPARE(), QVERIFY(), et ainsi de suite. Vous pouvez alors signaler un résultat de performance comme invalide si un autre chemin de code que celui prévu a été mesuré. Un outil d'analyse des performances peut utiliser ces informations pour filtrer les résultats non valides. Par exemple, une condition d'erreur inattendue entraînera généralement une interruption prématurée de l'exécution normale du programme, ce qui se traduira par une augmentation spectaculaire des performances.

Sélection du back-end de mesure

Le code contenu dans la macro QBENCHMARK sera mesuré et éventuellement répété plusieurs fois afin d'obtenir une mesure précise. Cela dépend du back-end de mesure sélectionné. Plusieurs back-end sont disponibles. Ils peuvent être sélectionnés sur la ligne de commande (voir Options de benchmarking) :

NomArgument de la ligne de commandeDisponibilité
Temps d'attente(par défaut)Toutes les plateformes
Compteur de tic-tac du processeur-tickcounterWindows, macOS, Linux, nombreux systèmes de type UNIX.
Compteur d'événements-eventcounterToutes les plateformes
Valgrind Callgrind-callgrindLinux (si installé)
Linux Perf-perfLinux

En résumé, le temps d'attente (walltime) est toujours disponible mais nécessite de nombreuses répétitions pour obtenir un résultat utile. Les compteurs de tics sont généralement disponibles et peuvent fournir des résultats avec moins de répétitions, mais peuvent être sensibles aux problèmes de mise à l'échelle de la fréquence du processeur. Valgrind fournit des résultats exacts, mais ne prend pas en compte les temps d'attente des E/S et n'est disponible que sur un nombre limité de plateformes. Le comptage d'événements est disponible sur toutes les plateformes et fournit le nombre d'événements reçus par la boucle d'événements avant qu'ils ne soient envoyés à leurs cibles correspondantes (cela peut inclure des événements non Qt).

La solution Linux Performance Monitoring n'est disponible que sous Linux et fournit de nombreux compteurs différents, qui peuvent être sélectionnés en passant une option supplémentaire -perfcounter countername, telle que -perfcounter cache-misses, -perfcounter branch-misses ou -perfcounter l1d-load-misses. Le compteur par défaut est cpu-cycles. La liste complète des compteurs peut être obtenue en lançant n'importe quel exécutable de benchmark avec l'option -perfcounterlist.

  • L'utilisation du compteur de performances peut nécessiter d'autoriser l'accès à des applications non privilégiées.
  • Les appareils qui ne prennent pas en charge les compteurs à haute résolution ont par défaut une granularité d'une milliseconde.

Voir Writing a Benchmark dans le Qt Test Tutorial pour plus d'exemples de benchmarking.

Utilisation des données de test globales

Vous pouvez définir initTestCase_data() pour mettre en place un tableau de données de test global. Chaque test est exécuté une fois pour chaque ligne du tableau de données de test global. Lorsque la fonction de test elle-même est pilotée par les données, elle est exécutée pour chaque ligne de données locales, pour chaque ligne de données globales. Ainsi, s'il y a g lignes dans le tableau de données global et d lignes dans le tableau de données du test, le nombre d'exécutions de ce test est g fois d.

Les données globales sont extraites du tableau à l'aide de la macro QFETCH_GLOBAL().

Les cas d'utilisation typiques des données de test globales sont les suivants :

  • Sélection parmi les bases de données disponibles dans les tests QSql pour exécuter chaque test avec chaque base de données.
  • Exécution de tous les tests de réseau avec et sans SSL (HTTP versus HTTPS) et proxy.
  • Test d'une minuterie avec une horloge de haute précision et avec une horloge grossière.
  • Choisir si un parseur doit lire à partir d'un QByteArray ou d'un QIODevice.

Par exemple, pour tester chaque nombre fourni par roundTripInt_data() avec chaque locale fournie par initTestCase_data():

void TestQLocale::roundTripInt()
{
    QFETCH_GLOBAL(QLocale, locale);
    QFETCH(int, number);
    bool ok;
    QCOMPARE(locale.toInt(locale.toString(number), &ok), number);
    QVERIFY(ok);
}

Sur la ligne de commande d'un test, vous pouvez passer le nom d'une fonction (sans préfixe de nom de classe de test) pour exécuter uniquement les tests de cette fonction. Si la classe de test possède des données globales, ou si la fonction est pilotée par les données, vous pouvez ajouter une balise de données, après deux points, pour exécuter uniquement l'ensemble de données de cette balise pour la fonction. Pour spécifier à la fois une balise globale et une balise spécifique à la fonction de test, combinez-les en les séparant par deux points, en plaçant la balise de données globale en premier. Par exemple

./testqlocale roundTripInt:zero

exécutera le cas-test zero du test roundTripInt() ci-dessus (en supposant que sa classe TestQLocale ait été compilée en un exécutable testqlocale) dans chacune des localités spécifiées par initTestCase_data(), tandis que

./testqlocale roundTripInt:C

exécutera les trois cas de test de roundTripInt() uniquement dans la locale C et

./testqlocale roundTripInt:C:zero

n'exécutera le cas-test zero que dans les paramètres linguistiques C.

Un contrôle aussi fin des tests à exécuter peut faciliter considérablement le débogage d'un problème, puisqu'il suffit de passer en revue le cas de test qui a échoué.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.