Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
💥 Du 22 au 24 novembre : Accès 100% GRATUIT
à la Bibliothèque Numérique ENI. Je m'inscris !
  1. Livres et vidéos
  2. Maîtrisez Qt
  3. Qt Test
Extrait - Maîtrisez Qt Guide de développement d'applications professionnelles (3e édition)
Extraits du livre
Maîtrisez Qt Guide de développement d'applications professionnelles (3e édition)
1 avis
Revenir à la page d'achat du livre

Qt Test - qualité du code

Objectifs

Pendant la vie d’une application, celle-ci est amenée à évoluer : maintenance corrective ou évolutive, le code est souvent remanié et des classes sont ajoutées, d’autres supprimées, des fonctionnalités sont ajoutées et parfois, au bout d’un moment, l’application commence à ne plus fonctionner correctement et on ne sait plus comment y remédier.

Les causes de ces problèmes sont souvent à chercher du côté de la conception et de l’architecture de l’application, néanmoins il devrait être toujours possible de s’assurer qu’une application fonctionne selon les besoins énoncés, et ce même après une correction. En effet, une correction peut parfois entraîner l’apparition d’autres bugs, appelés pudiquement effets de bord.

L’objectif de ce chapitre est de démontrer comment il est possible de mettre en place des tests unitaires dans vos programmes de manière à tester les fonctions que vous avez codées ainsi que les fonctionnalités attendues de l’application. Grâce à une API complète qui va jusqu’à vous permettre de simuler les interactions avec l’interface graphique, vous pourrez assurer une bonne couverture de tests et faire en sorte d’éviter les régressions...

Intégration

Le module QtTest est intégré à votre projet grâce à l’ajout du mot-clé testlib dans la déclaration QT de votre fichier .pro.

QT += testlib 

Scénario de tests

Il est utile de mettre en place plusieurs scénarios de tests dans une application. Un scénario correspond à un ensemble plus ou moins cohérent de tests qui seront effectués successivement.

Le choix de la cohérence est laissé au développeur ou au concepteur des tests. Il pourra s’agir, par exemple, de tester toutes les classes du domaine dans un même scénario, puis toutes les classes DAO dans un autre scénario, et ainsi de suite, couche par couche. Ou encore, vous pourrez choisir de tester de manière transversale, par fonctionnalité : une action, un ou plusieurs DAO et les classes correspondantes dans le domaine.

images/14_SC_01.png

Dans l’exemple ci-dessus, le scénario 1 consistera à concevoir des tests sur une partie du modèle, en l’occurrence les employés et les groupes. Le créateur des tests a choisi de tester individuellement les classes DAO et les entités.

images/14_SC_02.png

Dans le second scénario, le créateur des tests a choisi de tester une ou plusieurs fonctionnalités, voire un ou plusieurs événements. Par exemple cela pourrait consister à tester l’enregistrement en base d’une fiche d’employé après validation de la saisie par l’utilisateur. Le test consistera à simuler une saisie et un clic de bouton pour ensuite lire les données en base...

Tests unitaires et couverture de code

La création des tests unitaires est très simple, elle repose sur l’utilisation des slots et une structure de classe spécifique.

Pour créer un test unitaire ou un groupe de tests unitaires, vous devez créer une nouvelle classe C++ héritant de la classe QObject et lui attribuer au moins deux slots :

  • void initTestCase() : sera appelé automatiquement lors du démarrage de votre test ou série de tests. Cette fonction est utile pour initialiser l’environnement de test, par exemple en initialisant la connexion à une base de données.

  • void cleanupTestCase() : sera appelé automatiquement à la fin de l’exécution des tests. Cette fonction permet de nettoyer l’environnement de tests, en fermant la connexion précédemment ouverte et en supprimant les instances créées.

Pour exécuter votre ou vos tests, vous devez créer un ou plusieurs slots et les déclarer dans votre fichier en-tête. Tous les slots présents seront exécutés l’un après l’autre, dans l’ordre de déclaration.

images/14_SC_03.png

Le seul fait de déclarer un slot et de l’implémenter suffit à le rendre exécutable. Les tests échoués ne provoquent pas nécessairement l’arrêt de l’exécution du scénario, sauf si vous le précisez.

1. Les assertions

Qt Test fait un usage important des macros du précompilateur C. Les assertions sont toutes présentées sous la forme de macro :

  • QCOMPARE(valeur, reference) : compare une valeur résultant d’une opération avec une valeur de référence.

  • QFAIL(message) : provoque l’arrêt de l’exécution du scénario avec un message d’erreur.

  • QSKIP(message) : provoque la fin de l’exécution du test sans arrêter l’exécution du scénario.

  • QTRY_COMPARE_WITH_TIMEOUT(valeur, reference, timeout) : permet de comparer deux valeurs de manière répétée jusqu’à ce qu’elles soient égales ou que le timeout soit atteint. Les événements de la run-loop sont exécutés pendant ce temps, permettant aux autres...

Non-régression

Grâce à ces outils de tests, Qt vous permettra d’obtenir un code de qualité et de vérifier à la fois que votre implémentation couvre bien l’ensemble des fonctionnalités prévues, que les performances répondent aux exigences et que l’interface homme-machine n’est pas une source de défaillance.

Nous vous recommandons, à chaque fois que vous découvrez un bug dans votre programme, de procéder comme suit afin d’améliorer continuellement la qualité du programme et d’être certain de ne jamais subir de régression dans votre code :

1.

Identification du bug.

2.

Reproduction du bug.

3.

Création d’un test unitaire ou fonctionnel permettant de tester la non-présence du bug. Le test doit se solder par un échec.

4.

Correction du bug.

5.

Exécution des tests, les tests doivent tous passer.

En procédant ainsi, vous aurez toujours un test qui permet de couvrir le cas d’erreur que vous avez rencontré, et après différentes corrections et évolutions le cas ne se représentera plus.