La dernière version de Qt Creator 4.3.0 bénéficie d’une nouvelle fonctionnalité remarquable : la gestion des Tests ! Auparavant, pour faire cela, il fallait fabriquer soi-même un gestionnaire ou utiliser un outil tiers. Maintenant, exécuter les tests unitaires depuis Qt Creator devient un jeu d’enfant, alors plus aucune excuse pour faire des tests unitaires !
La nouvelle interface permet de gérer les tests Qt Tests (C++), Quick Test (QML) et Google Tests. On peut choisir de les exécuter tous en même temps, pratique pour valider un projet, ou bien individuellement pour valider une nouvelle classe ou méthode. Sélectionnez la vue “Test” dans le panneau de droite et dans la panneau de sortie, cliquez sur le bouton “Test results” pour voir les résultats.
L’application montrée ci dessous dispose de tests unitaires Qt Tests. Aller dans le menu “Outils” / “Tests” / “Rescan Tests” si ces derniers n’apparaissent pas.
L’organisation du projet est découpée en trois parties : une application, une librairie et des tests unitaires. Ce découpage permet de concentrer les test unitaires sur la librairie, et les tests fonctionnels sur l’application. Pour plus de détails sur l’organisation du projet, vous pouvez référer à l’article “Regrouper application, librairies et tests dans un seul projet Qt”.
Trois types de tests sont disponibles dans l’interface :
Dans cet article, il sera question uniquement des tests en C++ Qt Test. Pour aller plus loin sur les autres types de tests, commencez par regarder cet article : Running Autotests.
Ce n’est pas une obligation, mais bien souvent on va avoir une correspondance entre une classe et un projet de tests, par exemple :
Les méthodes
A contrario, les méthodes
A la place de QTEST_MAIN, on utilise QTEST_APPLESS_MAIN() car il n’y a pas de GUI, ni d’objet de type QObject disposant de signaux et de slots à tester. Donc inutile d’instancier un objet de type QApplication, ni de lancer la boucle d’événements. L’inclusion du fichier .moc est nécessaire dans le cas où la déclaration et l’implémentation de la classe sont dans le même fichier.
fichier
L’exécution de tous les tests ou bien le ciblage d’un en particulier autorise ainsi une grande souplesse d’utilisation.
Dans chaque méthode de test, il peut y avoir la présence d’une ou plusieurs vérifications de type
Pour avoir plus de détails, il faut faire un “run” du projet de test individuellement en rajoutant l’option
Enfin, quand on déplie les différents résultats, on retrouve également les informations de debug (
Personnellement, c’est un soulagement, plus besoin de créer une fonction en C++ ou en Perl chargée de lancer les tests et d'interpréter les résultats dans la jungle d’un fichier XML… Donc chapeau aux développeurs et merci pour cette super fonctionnalité !
La nouvelle interface permet de gérer les tests Qt Tests (C++), Quick Test (QML) et Google Tests. On peut choisir de les exécuter tous en même temps, pratique pour valider un projet, ou bien individuellement pour valider une nouvelle classe ou méthode. Sélectionnez la vue “Test” dans le panneau de droite et dans la panneau de sortie, cliquez sur le bouton “Test results” pour voir les résultats.
L’application montrée ci dessous dispose de tests unitaires Qt Tests. Aller dans le menu “Outils” / “Tests” / “Rescan Tests” si ces derniers n’apparaissent pas.
L’organisation du projet est découpée en trois parties : une application, une librairie et des tests unitaires. Ce découpage permet de concentrer les test unitaires sur la librairie, et les tests fonctionnels sur l’application. Pour plus de détails sur l’organisation du projet, vous pouvez référer à l’article “Regrouper application, librairies et tests dans un seul projet Qt”.
Qt Tests
Trois types de tests sont disponibles dans l’interface :
- Qt Test : tests unitaires en C++
- Quick tests : les tests unitaires en QML
- Google Test : tests nécessitant l’installation du framework Google.
Dans cet article, il sera question uniquement des tests en C++ Qt Test. Pour aller plus loin sur les autres types de tests, commencez par regarder cet article : Running Autotests.
Classes de tests
Chaque groupement de tests (TestListPerson
, TestPerson
dans l'exemple ci-dessous) correspond à une classe en C++. Chacune de ces classes est définie dans un projet indépendant (tst_ListPerson
, tst_Person
) qui dispose de sa propre fonction main()
.Ce n’est pas une obligation, mais bien souvent on va avoir une correspondance entre une classe et un projet de tests, par exemple :
- classe
Person
correspond au projet de tests unitairestst_Person
- classe
ListPerson
correspond au projet de tests unitairestst_ListPerson
Méthode de tests
Sous chaque classe de test, apparaît la liste des tests à proprement dit. Cette liste correspond à chaque méthode définie dans la classe en tant que “private slots”.class TestListPerson : public QObject { Q_OBJECT public: TestListPerson(); ~TestListPerson(); private slots: void initTestCase(); void cleanupTestCase(); void init(); void cleanup(); void testAdd(); void testSearch(); void testAverageAge(); };
Les méthodes
initTestCase()
et cleanupTestCase()
sont appelées avant et après l’exécution des tests de la classe. Elles peuvent contenir des vérifications, comme par exemple tester le constructeur et le destructeur de la classe. C’est pour cela qu’en plus des méthodes testAdd
, testSearch
et testAverageAge
, on les voit apparaître dans le panneau de résultats.A contrario, les méthodes
init()
et cleanup()
ne sont pas visibles en tant que résultat de test. Elles sont appelées avant et après l’exécution de chacune des méthodes de tests (testAdd
, testSearch
et testAverageAge
). Elles n’ont pas pour vocation de vérifier une condition mais plutôt d’initialiser et nettoyer un contexte. Pour allez plus loin dans le concept de tests unitaires, lire le tutoriel de la documentation de Qt : Qtest Tuorial.
Fonction main()
Généralement, pour simplifier l’écriture d’un projet de tests, on fait appel à la macro QTEST_MAIN(Object) pour générer la méthode main qui instanciera les bons objets et exécutera les tests. A la fin du fichier décrivant la classeTestListPerson
, on aura quelque chose comme ceci :QTEST_APPLESS_MAIN(TestListPerson) #include "tst_testlistperson.moc"
A la place de QTEST_MAIN, on utilise QTEST_APPLESS_MAIN() car il n’y a pas de GUI, ni d’objet de type QObject disposant de signaux et de slots à tester. Donc inutile d’instancier un objet de type QApplication, ni de lancer la boucle d’événements. L’inclusion du fichier .moc est nécessaire dans le cas où la déclaration et l’implémentation de la classe sont dans le même fichier.
Fichier de définition du projet
Au niveau de la configuration de chaque projet de tests, il faut définir dans le fichier.pro
l’option de config “testcase” (CONFIG += testcase
). Voici un exemple simple de test :fichier
tst_ListPerson.pro
include (../../../app.pri) QT += testlib QT -= gui CONFIG += qt console warn_on depend_includepath CONFIG += testcase CONFIG -= app_bundle TEMPLATE = app SOURCES += tst_testlistperson.cpp
Exécution des tests
L’exécution des tests devient un jeu d’enfant. Un clique droit sur le label “Qt Test”, et c’est parti pour l’exécution de tous les tests, ou bien de ceux uniquement sélectionnés. Un clique droit sur un test en particulier, pour n’exécuter que ce dernier, etc.L’exécution de tous les tests ou bien le ciblage d’un en particulier autorise ainsi une grande souplesse d’utilisation.
Lecture des résultats
Le panneau de droite “Tests results” montre les résultats des tests avec un code couleur. Soit toutes les vérifications ont réussi, et dans ce cas, il est marqué “PASS” en vert. Soit l’une des vérifications a échoué, et il est marqué comme FAIL. En cliquant sur la ligne “FAIL”, on obtient plus d’information sur l’erreur et sa nature. En double cliquant sur la ligne FAIL, Qt Creator ouvre le fichier et positionne le curseur sur le test qui a échoué.Dans chaque méthode de test, il peut y avoir la présence d’une ou plusieurs vérifications de type
QVERIFY
, QVERIFY2
, QCOMPARE
… Le panneau de résultat ne détaille pas toutes les vérifications. Quand l’ensemble des tests sont vérifiés, le panneau affiche “PASS” pour la méthode compléte, sans détails.Pour avoir plus de détails, il faut faire un “run” du projet de test individuellement en rajoutant l’option
“-v2”
dans la ligne de commande pour l’exécution.Enfin, quand on déplie les différents résultats, on retrouve également les informations de debug (
qDebug, qWarn, qInfo, qFatal
), ce qui peut s’avérer fort utile.Conclusion
Cet outil graphique de gestion des tests comble une lacune importante de l’IDE Qt Creator. Il facilite grandement la tâche des développeurs, en proposant l’exécution des tests unitaires et en affichant les résultats. La difficulté étant d’organiser correctement son projet afin de rendre tout cela possible.Personnellement, c’est un soulagement, plus besoin de créer une fonction en C++ ou en Perl chargée de lancer les tests et d'interpréter les résultats dans la jungle d’un fichier XML… Donc chapeau aux développeurs et merci pour cette super fonctionnalité !
Aucun commentaire:
Enregistrer un commentaire