Prouver le bon fonctionnement d'un logiciel avec le Toolkit Unit Test Framework

Aperçu

Cet article fait partie d'une série de documents relatifs aux pratiques et outils de génie logiciel pour le développement d'applications d'envergure dans LabVIEW.

Cliquez ici pour afficher la liste des autres articles

Détecter des bugs et les résoudre lors du développement d'un logiciel peut s'avérer difficile et coûteux, et demander beaucoup de temps. Assez logiquement, la validation peut facilement s'avérer encore plus contraignante et demander davantage de travail. Au fur et à mesure que les logiciels dans les applications exécutables gagnent en complexité, les développeurs ont besoin de procédures plus automatisées et « carrées » pour garantir la précision des tests et simplifier la validation du code. De plus, les logiciels utilisés dans les outils de test pour la production d'un produit critique ou complexe sont confrontés à une analyse accrue et, par conséquent, bon nombre des pratiques de génie logiciel dédiées au test et à la validation sont également applicables.

Contenu

Le test et la validation conformément aux exigences est une phase incontournable du processus de génie logiciel et une pratique standard pour quiconque doit apporter la preuve d'un bon fonctionnement. Prouver le bon fonctionnement d'un logiciel est bien plus complexe que le simple fait de montrer que l'application s'exécute ; il faut également valider le fait qu'elle fonctionne correctement. Cette tâche requiert de la documentation et des résultats de test qui démontrent que l'application se comporte de manière conforme à sa conception – preuve susceptible d'être exigée par le client, par un groupe de contrôle de la qualité, ou même par des organismes de régulation, comme la FDA ou la FAA. 

Télécharger la version d'évaluation valable 30 jours pour Windows XP/Vista

Présentation vidéo sur le Toolkit Unit Test Framework

Informations d'achats pour le Toolkit Unit Test Framework

Outils de test logiciel pour LabVIEW

Les développeurs LabVIEW ont à leur disposition de nombreux outils au sein de l'environnement LabVIEW, ainsi que de nombreux autres outils de génie logiciel pour le test et l'analyse de code avancés. Cet article est consacré au Toolkit Unit Test Framework, un outil LabVIEW qui sert à automatiser le test unitaire, la validation conformément aux exigences et le test de régression de VIs. 

Pour en savoir plus sur les outils complémentaires dédiés au génie logiciel, rendez-vous sur ni.com/softwareengineering

Introduction au test unitaire

L'idée derrière le test unitaire est d'une grande simplicité, mais elle peut être développée pour permettre une série de tests élaborés pour la validation de code et le test de régression. Un test unitaire est au sens strict quelque chose qui met en œuvre ou exécute le code sous test. Bon nombre de développeurs effectuent manuellement des tests unitaires de manière régulière lorsqu'ils travaillent sur un segment de code. En d'autres termes, cela peut être aussi simple que  ‘Je sais que le code est censé effectuer cette tâche lorsque j'applique cette entrée ; je fais un essai pour voir ce qui se passe.’  Si le comportement n'est pas conforme aux attentes, le développeur devra probablement modifier le code et répéter ce processus itératif jusqu'à ce que cela fonctionne.

Le problème avec le test manuel est qu'il peut facilement négliger de vastes gammes de valeurs ou différentes combinaisons d'entrées et qu'il n'offre aucune information sur la quantité de code qui a réellement été exécutée au cours du test. En outre, cela ne résout en rien la nécessité de prouver à une tierce personne que le code a fonctionné et qu'il a fonctionné correctement. Les coûts et le temps nécessaires sont décuplés par le fait qu'un seul et unique jeu de test est rarement suffisant ; outre la résolution de bugs, toute modification apportée au code de manière tardive dans le processus de développement risque d'entraîner un surcroît d'investissement en termes de temps et de ressources afin de garantir qu'il fonctionne correctement.

Les projets de grande envergure augmentent le plus souvent les procédures manuelles mais des outils comme le Toolkit Unit Test Framework permettent d'automatiser et d'améliorer ce processus. L'automatisation réduit le risque d'erreurs passées inaperçues, diminue les coûts en détectant les problèmes précocement et fait gagner du temps en permettant aux développeurs de se concentrer sur l'écriture du logiciel au lieu d'effectuer les tests eux-mêmes. 

Créer un test pour un VI LabVIEW

Pour créer un test dans LabVIEW avec le Toolkit Unit Test Framework, effectuez un clic droit sur le VI sous test dans l'Explorateur de projet et déplacez votre curseur sur l'élément de menu 'Unit Tests’. Sélectionnez ‘New Test’ pour créer un nouveau fichier sur le disque avec une extension .lvtest (voir Figure n°1). 

Figure n°1. Générer automatiquement un test pour un VI depuis le menu de l'Explorateur de projet.

Par défaut, ce fichier sera sauvegardé au même emplacement que le VI sous test ; cependant, les fichiers .lvtest peuvent automatiquement être stockés à un emplacement prédéterminé, comme cela est spécifié dans les propriétés du Toolkit Unit Test Framework (disponibles à partir de la boîte de dialogue des propriétés en effectuant un clic droit sur le fichier .lvproj dans l'Explorateur de projet).

Définir les vecteurs de test

L'étape suivante dans la création d'un test est la définition d'un vecteur de test ou un jeu de test. Les VIs, à l'instar des appels de fonction dans les langages de programmation textuels, ont des entrées et des sorties. Lorsqu'un test d'unité est effectué dans LabVIEW, un ensemble d'entrées défini est fourni au VI. Ces entrées sont associées à un ensemble prédéterminé de sorties attendues dans le but de définir un vecteur de test. La sortie du VI après exécution est ensuite comparée avec ce qui était attendu (voir Figure n°2) pour générer les résultats. Le Toolkit Unit Test Framework permet la création de ces tests sans aucune modification de code.

Figure n°2. Les vecteurs de test renvoient à l'association des entrées pour une unité de code avec les sorties attendues. Le test unitaire compare les résultats attendus avec les résultats réels pour générer des rapports.

Les jeux de tests peuvent être spécifiés de différentes manières avec le Toolkit Unit Test Framework. Le mécanisme le plus courant est la boîte de dialogue qui apparaît dans LabVIEW lorsque vous double-cliquez sur un fichier .lvtest dans l'Explorateur de projet. Dans la boîte de dialogue qui apparaît, sélectionnez ‘Test Cases’ dans la liste des catégories afin de spécifier les entrées et les sorties attendues. Par défaut, vous pouvez spécifier les valeurs d'entrées pour toutes les commandes attachées au connecteur et spécifier les valeurs de sorties attendues pour chaque indicateur relié au connecteur (voir Figure n°3).  

Figure n°3. Configuration des jeux de test dans la boîte de dialogue du Toolkit Unit Test Framework en double-cliquant sur un test dans l'Explorateur de projet.

La comparaison réalisée au niveau de la sortie est spécifique au type de données.

Si vous avez des entrées supplémentaires qui ne sont pas attachées au connecteur ou si vous souhaitez évaluer les entrées et les sorties, vous pouvez configurer tout cela en recourant à la catégorie avancée dans les options de configuration (voir Figure n°4). Les sorties peuvent également être exclues de la comparaison en désélectionnant l'option appropriée dans 'Test Case'.

Figure n°4. Le comportement par défaut utilise uniquement des commandes et des indicateurs sur le connecteur pour le jeu de test. Il est possible d'étendre cette utilisation à toutes les commandes et tous les indicateurs en modifiant la configuration avancée.

Comme avec n'importe quel langage de programmation, les entrées qui ne sont pas limitées ont un nombre infini de valeurs. Pour cette raison, les entrées qui représentent de multiples valeurs à partir d'une certaine gamme sont sélectionnées, mais des tests exhaustifs risquent de s'avérer impossibles.

Un seul et unique fichier .lvtest peut contenir plusieurs jeux de tests. Par exemple, vous pouvez créer un test qui évalue les performances du VI lorsqu'il reçoit une entrée incorrecte ; cependant, il y a probablement un grand nombre de combinaisons d'entrées qui rentrent dans cette catégorie et feraient donc partie du même test, mais chacune d'entre elles nécessiterait la définition d'un nouveau jeu de test. Pour ajouter des jeux de tests supplémentaires, cliquez sur ‘New’ dans la catégorie ‘Test Cases’ (voir la Figure n°5).

Figure n°5. Un seul et même test peut englober plusieurs jeux de tests.

Outre l'utilisation de la catégorie ‘Test Cases’ de cette boîte de dialogue, les vecteurs de test peuvent également être spécifiés dans un éditeur externe, comme Microsoft Excel, pour faciliter la création de tests par programmation. Cette caractéristique permet également à des groupes qui n'ont pas accès à l'environnement de développement de définir des tests. 

Options avancées de configuration des tests

Les VIs qui ont un état ou nécessitent d'être configurés par programmation sont susceptibles de devoir recourir à des VIs de paramétrage et de démontage pour suivre le test. La sortie du VI de paramétrage peut être transmise au VI sous test. Ceci s'avère utile si vous avez besoin de générer une entrée complexe par programmation, comme un signal de grande taille, ou peut-être de préparer un fichier ou une base de données pour un test (voir la Figure n°6). Cela peut également servir à transmettre une référence à un fichier ou à un objet que vous souhaitez voir utilisé par le VI sous test.

Figure n°6. Utilisez les VIs de paramétrage et de démontage afin de générer des entrées ou de configurer des conditions de test par programmation pour des jeux de tests plus avancés.

De plus, des filtres peuvent être définis dans le but d'exécuter uniquement les tests qui respectent une certaine priorité ou qui n'ont pas été lancés depuis une certaine date.

Définir les exigences de test

Générer des tests sans comprendre préalablement ce que le code est censé faire et comment il est censé se comporter est le plus souvent inefficace, car cela se traduit par des tests qui tentent de satisfaire les critères du développeur au lieu de répondre aux exigences d'une application.

Afin d'éviter un scénario dans lequel un développeur crée ses propres tests qui peuvent être facilement partagés, une attention particulière doit être accordée à la définition des exigences. Pour les ingénieurs, la tâche qui consiste à rassembler les exigences et à définir les spécifications relatives au comportement du code est la toute première d'une série d'étapes nécessaires au développement d'un logiciel. C'est le plus souvent au cours de ce processus que des tests efficaces sont définis et que le comportement attendu du code est déterminé. 

Figure n°7. Ceci est un exemple des relations complexes qui existent entre les documents relatifs aux exigences, les mises en œuvre, les tests d'unités et les rapports.

Les exigences des tests sont fréquemment le fruit de différentes séries de prototypage et de démonstrations de faisabilité qui sont présentées à un client afin de définir ce que fera le produit fini. Il est important de bien établir la distinction entre ces efforts pour définir le comportement de l'application en termes d'exigences et le processus de développement d'un logiciel professionnel, haute qualité et d'une grande fiabilité.

Des projets à haut risque ou critiques vont généralement débuter avec des exigences poussées au point de définir comment les unités individuelles du code seront implémentées et quelles seront leurs sorties spécifiques dans des conditions normales ou erronées. C'est à partir de ces définitions que les critères d'évaluation des tests d'unité peuvent être établis.

Couverture des exigences

La validation du logiciel consiste en grande partie à démonter où et comment les exigences ont été couvertes. Dans bien des cas, cela nécessite la création d'une matrice de traçabilité, qui relie l'exigence avec l'emplacement au niveau du code où elle a été couverte. En fonction du niveau d'analyse, il peut également s'avérer nécessaire de démontrer où les tests destinés au logiciel ont été mis en œuvre. Pour cette raison, le Toolkit Unit Test Framework permet aux développeurs d'entrer un ou plusieurs Requirements IDs dans la catégorie ‘Configuration’ (voir Figure n°8). 

Figure n°8. Le Toolkit Unit Test Framework s'intègre avec Requirements Gateway afin d'automatiser la traçabilité dans le cadre des spécifications relatives aux tests.

Cet ID des exigences peut être analysé par l'outil de gestion des exigences de National Instruments, NI Requirements Gateway, afin d'automatiser la gestion des exigences de test et suivre leur couverture.  

Apprendre à combiner NI Requirements Gateway avec le Toolkit Unit Test Framework.

Les exigences qui définissent comment le code sera implémenté et comment les tests seront effectués sont généralement remplies et considérées comme "verrouillées" avant le début du développement – tout particulièrement dans le cas d'un modèle de processus de développement reposant sur les tests. Dans la réalité toutefois, les modifications des exigences sont pratiquement inévitables à la suite de changements imprévus. C'est la raison pour laquelle il est nécessaire de conjuguer des outils de gestion des exigences et de gestion de la configuration afin d'éclairer l'utilisateur sur le code impacté et donc susceptible de devoir être validé à nouveau ou testé.  

En savoir plus sur la gestion de la configuration logicielle pour LabVIEW et le contrôle de code source.

Effectuer des tests

Les tests créés à l'aide du Toolkit LabVIEW Unit Test Framework peuvent être lancés de différentes façons :

  • Tests individuels : effectuez un clic droit dans l'Explorateur de projet et sélectionnez ‘run’
  • Par VI sous test : effectuez un clic droit sur le VI que vous souhaitez tester, et naviguez jusqu'à ‘Unit Tests > Run’
  • Tests dans un dossier : effectuez un clic droit dans le dossier et sélectionnez ‘Unit Tests > Run’
  • Tous les tests dans l'Explorateur de projet : cliquez sur ‘Run Unit Tests’ dans la barre d'outils de l'Explorateur de projet
  • Par programmation : utilisez les VIs sur la palette du Toolkit Unit Test Framework (voir Figure n°9)

Figure n°9. Le Toolkit Unit Test Framework installe une palette de VIs permettant d'automatiser l'exécution des tests et la génération de rapports.

Une fois que les tests ont été exécutés, leur succès ou leur échec est affiché sur l'icône à l'aide de points verts et rouges (respectivement). Une boîte de dialogue contenant les résultats apparaît et un rapport est généré si la génération de rapport est activée.

Couverture du code : garantir que l'ensemble du code a été testé

La couverture du code est une mesure utilisée pour renseigner la quantité de code qui a été ‘couverte’ ou exécutée au cours du test. En fonction du niveau de complexité et de risque, certaines autorités exigent que l'ensemble du code soit mis en œuvre afin de limiter le risque d'avoir du code non testé et des états d'applications susceptibles d'entraîner un comportement incorrect. 

Le Toolkit LabVIEW Unit Test Framework suit la couverture du code pour chaque vecteur de test individuel. Il rassemble ces pourcentages sur l'ensemble des tests afin d'identifier quelle partie du code n'a pas été couverte. La boîte de dialogue de résultats du Toolkit Unit Test Framework recense tous les pourcentages et documente le code non couvert. En cliquant sur cette énumération dans la boîte de dialogue, l'utilisateur affiche et met en évidence l'emplacement exact de ce code (voir Figure n°10).

Figure n°10. Suivre et identifier le code qui n'a pas été exécuté au cours des tests.

Génération de rapports

Apporter la preuve du bon fonctionnement requiert la création de documentation montrant que le logiciel remplit son objectif fixé et répond à tous les autres critères (voir Figure n°11). Le Toolkit LabVIEW Unit Test Framework permet la génération automatique de documentation aux formats XML (ATML), HTML ou ASCII. Les informations inclues dans ce rapport peuvent être configurées, mais comportent le plus souvent le temps de test, la durée de chacun des tests, les entrées des vecteurs de test, les résultats, et la somme des mesures de couverture du code.

Figure n°11. Des rapports sont générés automatiquement par le Toolkit Unit Test Framework afin de recenser tous les détails et les résultats des tests.

Conclusion

Le test et la mise au point d'un logiciel ont toujours fait partie intégrante du processus de développement, mais il existe des outils automatisés tels que le Toolkit LabVIEW Unit Test Framework pour relever les défis engendrés par le test des logiciels complexes. L'automatisation de ce processus permet aux développeurs de réduire le temps nécessaire aux tests tout en les rendant plus complets. Cela ne contribue pas seulement à garantir la meilleure qualité possible du logiciel, mais aussi à économiser de l'argent en détectant précocement d'éventuels problèmes et en réduisant le temps nécessaire à l'exécution de ces tests.