Découvrez GoogleTest certifié TÜV avec Agentic AI pour les tests C/C++ !
Plus de détails »
Aller à la section
Blog Parasoft
L'environnement le plus efficace pour les tests de développement est celui avec une solution de test unifiée profondément intégrée à l'IDE du développeur. Par exemple, les équipes peuvent concentrer les tests sur le code le plus récemment mis à jour et à haut risque grâce à un outil centralisé comme Parasoft C/C++test.
Aller à la section
Une solution de test unifiée avec une intégration profonde dans l'IDE du développeur fournit l'environnement le plus productif pour les tests de développement. Un outil unifié, tel que Parasoft C/C++test, permet aux équipes de concentrer leurs tests sur le code à haut risque et le plus récemment modifié.
La vérification et la validation logicielles sont des étapes essentielles du développement logiciel. Les efforts et le budget consacrés aux projets de V&V dépendent de nombreux facteurs, tels que les objectifs de sécurité fonctionnelle, le niveau de risque pour l'entreprise ou la culture qualité de l'organisation. Quelles que soient les motivations d'une organisation pour mettre en œuvre des initiatives et des processus qualité, la simple détermination ne suffit pas à garantir des logiciels sûrs et de haute qualité.
Choisir les méthodologies de test appropriées est une tâche complexe pour de nombreuses raisons. La technologie évolue rapidement et les entreprises doivent choisir les outils de test logiciel à adopter. Dans bien des cas, le choix entre les produits libres et les produits commerciaux s'avère également difficile.
Cet article explique comment combiner les techniques de test automatisées, telles que l'analyse statique avancée, la surveillance de la mémoire d'exécution, les tests unitaires automatisés et l'analyse de flux , afin d'améliorer les processus d'assurance qualité. Il met également en évidence les avantages de la mise en œuvre d'une solution de test unifiée. Les concepts abordés ici sont génériques et applicables à tout langage de programmation, mais les exemples présentés ici concernent les langages C et C++ et ont été créés avec Parasoft C/C++test.
Lors de la réflexion sur d'éventuels dysfonctionnements logiciels de haut niveau, plusieurs classes d'erreurs logicielles peuvent être distinguées: les erreurs résultant d'exigences manquantes, les erreurs causées par des exigences mal spécifiées et les erreurs qui se produisent parce que les exigences ont été mal codées. Les deux premières classes de défauts logiciels entrent dans la catégorie de l'ingénierie des exigences et ne seront pas abordées ici. Je me concentre ici sur les erreurs causées par une mise en œuvre incorrecte qui comprend un large éventail de problèmes logiciels potentiels avec lesquels de nombreuses équipes sont aux prises.
Alors, qu'est-ce que cela signifie qu'une exigence a été codée de manière incorrecte ? Cela peut être beaucoup de choses. Prenons, par exemple, une exigence mal implémentée - les tests unitaires conçus pour vérifier l'échec de l'implémentation correcte et les outils d'automatisation des tests détectent et signalent le défaut. Dans un autre exemple, un outil d'analyse d'exécution peut détecter une erreur critique d'accès à la mémoire pendant un test unitaire qui est indétectable à partir des résultats du test unitaire seuls. Différents outils sont plus efficaces pour détecter certaines classes d'erreurs, comme illustré ci-dessous.
Figure 1. Défauts logiciels et paysage de stratégies de détection.
De toute évidence, tous les projets logiciels n'ont pas besoin d'utiliser toutes les technologies disponibles pour tester et améliorer la qualité des logiciels, et les organisations sont confrontées au dilemme de l'équilibre entre budget et qualité. Les projets liés à la sécurité fonctionnelle sont susceptibles de sélectionner toutes les technologies disponibles pour garantir une qualité sans compromis, ainsi que le respect des normes de sécurité des logiciels, telles que l'ISO 26262. D'autres équipes peuvent décider de ne choisir que l'analyse statique et les tests unitaires, comme ils semblent le faire. couvrent une partie importante des défauts logiciels, tandis que certaines équipes peuvent trouver un cadre de test unitaire open source suffisant.
La réticence à mettre en œuvre un large éventail de technologies de test découle souvent d'une préoccupation selon laquelle l'utilisation de plusieurs techniques impose des frais généraux importants sur le rythme du développement, sans parler du budget. C'est probablement un problème réel si les équipes décident de sélectionner des outils non intégrés. Le coût de plusieurs outils distincts, la courbe d'apprentissage et la nécessité de basculer entre différents modèles d'utilisation et interfaces peuvent être problématiques. En conséquence, les développeurs peuvent éviter d'utiliser des outils et de l'automatisation, car cela redirige leur attention de l'écriture de code vers l'utilisation des outils, ce qui diminue leur productivité.
Il est important de préciser ce que l'on attend d'une solution de test unifiée avant de discuter de sa valeur. Idéalement, une solution devrait :
Une solution de test unifiée et intégrée permet d'éviter un certain nombre de problèmes :
Les défauts logiciels appartiennent à différentes catégories, on ne peut donc pas s'attendre à ce qu'ils soient tous identifiés par une seule technique de test. Par exemple, les tests manuels au niveau du système. Pour fournir un exemple plus concret, observez l'exemple d'extrait de code suivant :
Les quelques lignes de code ci-dessus présentent plusieurs problèmes. Plus précisément, à la ligne 16, le développeur tente d'initialiser un tampon global à l'aide de la valeur d'index calculée par la fonction `calculateIdx()` , sans vérifier si cette valeur se situe dans la plage autorisée. Même en effectuant de nombreux tests manuels, il est possible que ce problème ne soit pas détecté, car l'écriture d'une valeur entière à un emplacement mémoire aléatoire produit rarement un effet spectaculaire immédiat.
Mais un jour, très probablement après la publication, la disposition de la mémoire peut changer et l'opération à partir de la ligne 16 plante l'application. Il est intéressant de noter que l'analyse statique peut également échouer à signaler ce problème en raison de la boucle utilisée pour calculer l'indice. Pour des raisons de performances, l'analyse des flux de données et de contrôle utilisée dans les outils d'analyse statique doit appliquer des heuristiques et des simplifications pour terminer l'analyse du code dans un délai raisonnable, et il est courant de les appliquer en boucles, ce qui signifie que certaines erreurs peuvent être manquées.
Un outil de surveillance de la mémoire, qui instrumente le code source en injectant des contrôles spéciaux et signale des opérations de mémoire incorrectes, est certain de détecter cette erreur. Les outils d'analyse d'exécution détectent les problèmes logiciels uniquement sur les chemins réellement exécutés, sans faire de suppositions - un gros avantage par rapport à l'analyse statique, car la précision des problèmes signalés est très élevée.
Dans cet exemple, la détection des erreurs de mémoire de Parasoft a facilement identifié le problème:
La situation inverse est tout aussi possible : l’analyse statique peut détecter des problèmes que la surveillance de la mémoire à l’exécution ne peut pas identifier. Par exemple, une déréférencement de pointeur nul est possible aux lignes 27/28 de l’extrait de code ci-dessous. L’appel de la fonction `storePersonToFile` avec l’ argument ` person` nul provoque une erreur, mais uniquement si la fonction `retrievePersonFromDB` renvoie `null`. Une telle condition est peu probable lors des tests système, car la connexion à la base de données fonctionne généralement comme prévu, et les outils de surveillance de la mémoire à l’exécution restent silencieux. Cependant, l’analyse de flux effectuée par l’outil d’analyse statique détecte facilement le pointeur nul renvoyé par cette fonction et signale un potentiel problème de déréférencement de pointeur nul.
Figure 4. Exemple de résultats d'analyse statique.
Qu’en est-il du code qui s’exécute toujours parfaitement, mais qui ne respecte pas les exigences ? L’analyse statique et dynamique est inefficace pour identifier ce type de problème. Détecter les écarts entre le résultat attendu et le résultat obtenu nécessite de comparer les résultats de calcul à des valeurs prédéfinies. Il existe de nombreuses méthodes courantes pour effectuer ces vérifications, notamment les tests système manuels, les tests d’intégration et les tests unitaires.
Il existe de nombreux domaines dans lesquels une solution de test unifiée peut faciliter le processus de test unitaire. La liste des avantages comprend :
La création de tests avec des assistants graphiques ou des éditeurs peut augmenter la productivité de toute une organisation en engageant les équipes d'assurance qualité dans le processus d'écriture des tests unitaires, les faisant ainsi contribuer activement au processus de développement. Il est plus facile pour les membres de l'équipe d'assurance qualité d'utiliser des assistants graphiques que d'écrire le code de test approprié dans les éditeurs de code, car la configuration des valeurs à l'aide de formulaires de saisie (comme indiqué ci-dessous) ne nécessite pas de compétences de codage avancées et prend moins de temps, en particulier si les membres de l'équipe manquent d'expérience. . Par exemple, la capture d'écran ci-dessous montre un exemple de la capacité de test unitaire du test Parasoft C / C ++ pour C / C ++, un assistant qui aide à la création de test unitaire.
Un autre avantage de l'utilisation d'une solution de test unifiée réside dans le retour d'information qu'elle fournit sur l'exhaustivité des tests et l'état de santé des exigences métier critiques. Des valeurs faibles dans le rapport de couverture MC/DC peuvent indiquer une couverture insuffisante des branches, même si le rapport de couverture des instructions affiche des valeurs élevées. Ce type d'analyse nécessite une chaîne d'outils prenant en charge plusieurs métriques de couverture, permettant aux équipes de commencer par une approche simple, comme la couverture des lignes ou des instructions, et de progresser vers une couverture de code plus approfondie à mesure qu'elles améliorent leurs cas de test.
Les rapports de couverture des tests unitaires et des tests système sont d'excellentes sources d'information sur le processus de test, surtout lorsqu'ils sont combinés. Cependant, si les résultats des tests ne sont pas corrélés aux exigences, les équipes manquent d'informations cruciales. En consultant un rapport de traçabilité des tests aux exigences , vous pouvez rapidement déterminer l'état de la couverture des exigences. Un exemple de ce type de rapport est présenté ci-dessous :
La possibilité de corréler les exigences avec les résultats de différents types de tests est un grand avantage de l'utilisation d'une solution de test unifiée. Les tests unitaires, les tests système, les résultats des tests d'intégration, ainsi que les normes de codage et les résultats des métriques de code peuvent être corrélés pour fournir des informations sur la santé des exigences critiques et non critiques.
Lorsque vous combinez les données des différentes techniques de test utilisées dans un projet, vous pouvez obtenir des métriques de second niveau et des analyses plus sophistiquées. L'utilisation d'une solution de test unifiée permet aux équipes d'examiner le code sous un angle complètement nouveau. Un cas de test unitaire ayant échoué peut avoir une signification différente pour un développeur, selon qu'il se produit dans un code classé à risque élevé ou faible par l'analyse des métriques de code. Si ces informations sont encore combinées avec des statistiques du contrôle de source et corrélées aux exigences, les équipes peuvent prendre de meilleures décisions sur le moment et la manière dont le code doit être corrigé.
Avec la suite d'outils Parasoft, vous pouvez tirer parti des tests basés sur les modifications pour améliorer la productivité de l'équipe. La technologie de test basée sur les modifications capture la relation entre le code source, les cas de test et les résultats de couverture de code pour calculer l'ensemble optimal de cas de test pour la vérification et la validation d'un delta de code spécifique. En effet, les équipes peuvent limiter leurs sessions de test en n'exécutant qu'un petit sous-ensemble de tests au lieu de suites de régression complètes. Cette focalisation sur le test uniquement de ce qui est absolument nécessaire se traduit par des économies importantes, en particulier pour les projets de taille moyenne ou grande.
Toutes les technologies de test mentionnées ci-dessus sont disponibles dans Parasoft C/C++test et Parasoft DTP . Parasoft C/C++test est une solution de test unifiée pour les projets C et C++. C/C++test est disponible sous forme d'extension pour les environnements de développement intégrés (IDE) les plus courants, tels qu'Eclipse et Visual Studio. Son intégration étroite avec l'IDE permet d'éviter les problèmes évoqués précédemment.
Les développeurs peuvent exécuter instantanément des vérifications de conformité aux normes de codage ou exécuter des tests unitaires au moment de l'écriture du code. Les membres de l'équipe QA peuvent effectuer des scénarios de test manuels pendant que l'application est surveillée pour la couverture du code et les erreurs d'exécution. Des analyses hors ligne, telles que l'analyse de flux fournie par l'analyse statique, peuvent être effectuées dans la phase d'intégration continue.
Les sessions serveur, prises en charge avec une interface de ligne de commande pratique, rapportent les résultats d'analyse à Parasoft DTP, qui agrège les informations de l'environnement de développement. Parasoft DTP offre des fonctionnalités de création de rapports étendues, notamment la possibilité d'intégrer des données provenant d'outils tiers, d'envoyer les résultats des tests aux IDE des développeurs et de calculer des analyses avancées. Les commentaires continus fournis à chaque phase du flux de travail accélèrent le développement agile et réduisent le coût de mise en conformité avec les normes de sécurité.
Il convient également de noter que l'approche en matière de processus et d'architecture d'assurance qualité présentée ici ne se limite pas aux projets C/C++. Parasoft propose des solutions similaires pour Java et C#/.NET.
L'amélioration de la qualité des logiciels n'est pas une entreprise homogène et nécessite différentes technologies pour éradiquer différents types de défauts logiciels. Le principal défi est de savoir comment le faire de manière efficace et efficiente en évitant de dévaster les budgets des projets et de saper le moral des développeurs.
Une solution de test unifiée avec une intégration profonde dans l'IDE du développeur fournit l'environnement le plus productif pour les tests de développement. Un outil unifié, tel que Parasoft C/C++test, avec sa capacité à unifier les métriques et les résultats de tous les aspects des tests, offre un avantage supplémentaire en permettant aux équipes de concentrer leurs tests sur le code à haut risque et le plus récemment modifié.