Webinaire en vedette : MISRA C++ 2023 : tout ce que vous devez savoir | Voir le séminaire

Augmentez le retour sur investissement des tests unitaires grâce à la création automatique de tests unitaires

Portrait de Brian McGlauflin,
16 juin 2023
10 min lire

Utilisez l'outil de génération de tests unitaires automatisés Parasoft Jtest pour augmenter le retour sur investissement de vos tests unitaires. Poursuivez votre lecture pour apprendre à automatiser les aspects fastidieux des tests unitaires et à réduire la complexité des moqueries.

La technologie de création automatique de tests unitaires de Parasoft Jtest supprime les obstacles aux tests unitaires, automatisant les aspects banals des tests unitaires, y compris la création, l'isolement, la simulation et la maintenance.

La plupart des équipes de développement conviendront que, bien qu'elles ne l'aiment pas, les tests unitaires sont, en fait, extrêmement précieux. Malgré les nombreux outils qui aident à la création manuelle de tests, la création et la maintenance de tests unitaires nécessitent encore beaucoup d'efforts manuels, longs et souvent abrutissants avant d'ajouter une logique métier à un test. En tant que tel, malgré l'intention d'effectuer d'excellents tests unitaires, les équipes de développement effectuent généralement le minimum de tests unitaires requis ou les ignorent complètement.

Principales préoccupations des développeurs Java concernant les tests unitaires

Une récente enquête auprès des clients a révélé, de manière quelque peu attendue, que la création de tests, la simulation / l'isolement et la maintenance sont des problèmes clés qui entravent le succès des tests unitaires. La figure 1 montre les résultats de cette enquête, montrant les principales préoccupations que les développeurs identifient avec tests unitaires en Java.

Graphique montrant les résultats de l'enquête sur les principaux domaines de préoccupation des développeurs Java : temps de création (58 %), isolation et simulation (65 %), maintenance et entretien (65 %), temps d'exécution (8 %).
Les résultats de l'enquête montrent les principaux domaines de préoccupation en pourcentage qui découlent des tests unitaires.

Pour répondre à ces principaux sujets de préoccupation, nous pouvons nous tourner vers des tests logiciels automatisés. Dans ce blog, je vais vous montrer comment utiliser Jtest Parasoft pour créer automatiquement des tests unitaires, pour gagner du temps et de l'énergie au moment de la création des tests. Jtest de Parasoft technologie de création automatique de tests unitaires configure le cadre de test, instancie les objets, configure les simulations pour les objets appropriés et les appels de méthode utilisés par la méthode testée et ajoute des assertions. Il crée des JUnits réguliers, effectuant tout le travail banal afin que les développeurs puissent se concentrer sur l'application de l'intelligence et de la logique humaines à leurs tests.

Comprendre les fondamentaux des tests unitaires

Tout ingénieur logiciel qui comprend la nécessité de donner la priorité à un code de haute qualité et sans bogue dans le développement logiciel vous dira que les tests unitaires sont comme une base sur laquelle sont construits d'autres aspects de l'assurance qualité logicielle. Les tests unitaires garantissent que les unités individuelles ou les composants du code fonctionnent comme prévu. Cela implique de tester un petit morceau de code, généralement une fonction ou une méthode unique, isolé du reste du système.

Pour s'assurer que chaque unité de code fonctionne comme prévu et exécute la fonction attendue qui lui est assignée, les développeurs écrivent des cas de test manuellement ou avec des outils de création de tests unitaires automatiques. L'exécution de ces tests aide à identifier les bogues ou les erreurs dans le code avant qu'il ne soit intégré dans le système plus large. Leur exécution régulière garantit que ce qui fonctionne aujourd'hui continue de fonctionner à l'avenir.

Les tests unitaires sont devenus de plus en plus importants au fil des ans, à mesure que les systèmes logiciels sont devenus plus complexes et que le besoin de logiciels fiables a augmenté. Cependant, à tirer le meilleur parti des tests unitaires, il existe des politiques recommandées et des meilleures pratiques qui devraient guider le processus.

  1. Rédigez les cas de test suffisamment tôt. Il est important d'écrire vos cas de test tôt dans le processus de développement. Idéalement, lorsque vous écrivez du code ou même avant d'écrire du code, ce que l'on appelle le développement piloté par les tests ou TDD. Cela permet aux développeurs de détecter les bogues et les problèmes tôt lorsqu'ils sont plus faciles et moins coûteux à résoudre. Cette approche est également essentielle pour s'assurer que le logiciel est construit pour répondre aux exigences et aux spécifications énoncées dans la conception. L'écriture de tests parallèlement au code incite les développeurs à penser à la qualité tout au long du processus de développement.
  2. Les tests unitaires doivent être écrits pour être spécifiques et indépendants. Étant donné que l'objectif principal des tests unitaires est de tester des composants uniques ou des unités de code, les tests doivent être spécifiques et indépendants les uns des autres. En tant que tel, chaque test doit se concentrer sur le test d'une fonctionnalité ou d'un aspect spécifique du code et ne doit pas s'appuyer sur les résultats d'autres tests.
  3. Utilisez l'automatisation des tests. L'automatisation des tests implique l'utilisation d'outils logiciels pour écrire automatiquement des cas de test, exécuter des tests et évaluer les résultats. L'utilisation d'outils d'automatisation des tests peut faire gagner du temps et augmenter l'efficacité du processus de test. Cela permet également d'exécuter des tests plus fréquemment, garantissant que tous les problèmes ou bogues sont détectés dès le début.

Par exemple, la solution de tests unitaires automatisés de Parasoft offre aux développeurs de logiciels une génération de tests unitaires basée sur l'IA qui peut être déployée pour générer automatiquement et rapidement des cas de tests unitaires robustes et prêts à l'emploi. Il fournit également des outils IDE et CI/CD pour l'exécution, l'extension et la maintenance de ces tests au fur et à mesure que le code change, et l'analyse de métriques importantes telles que la couverture du code.

  1. Utilisez des simulations pour l'isolement des tests. Les simulations permettent aux développeurs d'isoler le code testé des autres composants ou systèmes, ce qui facilite la configuration des tests pour valider des cas d'utilisation spécifiques, identifier les problèmes et isoler les bogues. L'utilisation de simulations permet également d'exécuter les tests plus rapidement et plus efficacement. L'outil de test unitaire automatisé de Parasoft utilise des simulations dans les tests nouvellement générés et fournit des outils supplémentaires pour aider les utilisateurs à créer, mettre à jour et gérer des simulations dans leurs tests pour une isolation facile des tests.
  2. Utilisez des métriques de couverture de code. Les métriques de couverture de code mesurent le degré auquel le code source du logiciel est testé pour déterminer si le système a été suffisamment testé ou non. L'utilisation de mesures de couverture de code peut identifier les zones du code qui ne sont pas testées et garantir que tout le code est testé de manière approfondie. Les outils Parasoft peuvent collecter, agréger et analyser la couverture de code recueillie à partir de plusieurs niveaux de test pour aider les développeurs à tester minutieusement leurs applications. Les utilisateurs peuvent se concentrer sur la couverture de code modifiée pour optimiser leurs efforts de test et combler les lacunes de couverture plus tôt dans le flux de travail de développement logiciel.

Surmonter les principaux défis des tests unitaires

Bien que les tests unitaires soient cruciaux dans toute entreprise de développement de logiciels, ils peuvent également présenter plusieurs défis qui entravent leur efficacité. Vous trouverez ci-dessous quelques défis clés dans les tests unitaires et comment les surmonter.

  1. Atteindre efficacement les niveaux appropriés de couverture de code. Pour s'assurer que le code est suffisamment testé, les développeurs doivent donner la priorité aux tests des chemins de code critiques et complexes et utiliser outils de couverture de code pour identifier les domaines qui nécessitent des tests supplémentaires. La définition de ce qui constitue un test suffisant peut faire l'objet d'un débat, mais un objectif commun et raisonnable est une couverture de code de 80 %.

Le défi est que cela peut prendre beaucoup de temps et d'efforts pour atteindre des niveaux élevés de couverture de code et les tests unitaires sont souvent dépriorisés face aux calendriers et à la pression pour développer de nouvelles fonctionnalités. L'utilisation d'un outil automatisé comme Parasoft Jtest peut réduire considérablement le temps nécessaire à la création et à la maintenance des tests unitaires, ce qui rend possible la création d'un nombre suffisant de tests unitaires.

  1. Appliquer les bonnes pratiques de développement sur le code mis à jour. Il est courant que les équipes de développement mettent à jour les fonctionnalités des applications qui n'ont pas suffisamment de tests. Cela présente de nombreux risques car les tests servent de filet de sécurité pour garantir que le comportement de l'application ne change pas de manière inattendue. Les équipes peuvent atténuer ce risque en mesurant la couverture de code modifié, qui est un calcul de la quantité de code modifié (à la fois le nouveau code et l'ancien code qui a été modifié) qui est couverte par les tests. En appliquant des niveaux suffisants de couverture modifiée avec Parasoft Jtest, les équipes de développement peuvent s'assurer que leur code modifié est bien testé, même si de grandes parties du reste de l'application ne le sont pas.
  2. Exécution des tests appropriés pour vérifier les changements de code. Les développeurs doivent exécuter des tests existants dans leur IDE lorsqu'ils apportent des modifications au code pour s'assurer que leurs modifications n'interrompent pas les fonctionnalités existantes. Cependant, si leur base de code est volumineuse, ils peuvent ne pas comprendre quels tests doivent être exécutés, ils peuvent donc ignorer l'exécution des tests avant de valider le code.

De plus, après avoir validé le code, le processus CI/CD doit exécuter des tests unitaires pour vérifier les modifications. Lorsqu'il existe une grande suite de tests, ils peuvent ne pas s'exécuter aussi rapidement que souhaité. Parasoft Jtest identifie les tests impactés qui doivent être exécutés lorsque le code change, à la fois dans le processus IDE et CI/CD afin que les développeurs puissent identifier et exécuter un ensemble optimisé de modifications qui vérifient leurs modifications.

  1. Utiliser les types de tests appropriés pour le code testé. Les tests unitaires ne sont pas toujours les types de tests optimaux à utiliser pour couvrir des parties spécifiques du code. Les tests unitaires ne sont qu'un type de test et doivent être complétés par d'autres stratégies de test, telles que les tests d'API, les tests fonctionnels, les tests d'interface utilisateur, les tests de performances et les tests de sécurité. L'utilisation de tests unitaires avec d'autres stratégies de test nécessite d'investir dans des outils et des cadres appropriés. Les équipes doivent collecter des données de couverture de code à partir de toutes leurs pratiques de test, pour se donner une vue globale de la couverture de tous leurs tests - ce qui leur permet d'optimiser leurs efforts pour utiliser la stratégie de test la plus appropriée en fonction du code qu'ils testent.
  2. Ecrire du code testable. Le code testable est un code qui peut être facilement exercé par des tests unitaires et testé de manière isolée sans dépendre de dépendances externes. Un code qui repose fortement sur des dépendances ou des états externes peut être difficile à tester, ce qui conduit à des tests fragiles et peu fiables. Pour surmonter ce défi, les développeurs peuvent viser à écrire du code modulaire et faiblement couplé. Des frameworks tels que Mockito peuvent également être utilisés dans des tests pour aider à isoler le code testé de ses dépendances.

Avantages des tests unitaires et pourquoi les développeurs n'en font toujours pas assez

Les tests unitaires sont itératifs et, dans les processus Agiles, les tests unitaires ont de bons antécédents d'amélioration des résultats du projet. Il est bien prouvé que tester plus tôt dans le cycle de vie est le meilleur moyen de détecter et de supprimer les bogues coûteux et chronophages au niveau du système. Plus précisément, voici quelques avantages clés des tests unitaires.

  • Fournir de l'agilité pour les processus Agiles. Les processus agiles dépendent de suites de tests efficaces, reproductibles et automatisées afin de garantir que chaque itération ne s'enlise pas dans un cycle de test « big bang ». Le succès d'Agile et de DevOps dépend en grande partie des équipes de développement qui créent des suites de tests qui peuvent être exécutées efficacement, ainsi que de tester autant de fonctionnalités que possible.
  • Amélioration de la qualité et de la sécurité. Les équipes logicielles comprennent que les tests sont le seul moyen de s'assurer que le logiciel fait ce qui est requis, mais les équipes ne parviennent souvent pas à effectuer suffisamment de tests ou le font trop tard dans le cycle de vie du développement. La sécurité, en particulier, doit être intégrée à une application dès les premières étapes, de sorte que les tests de sécurité doivent être effectués le plus tôt possible.
  • Réduction des coûts à long terme. Les bogues logiciels trouvés dans les logiciels publiés peuvent être beaucoup plus coûteux à corriger que pendant le développement. Les bogues trouvés aux premières étapes de codage dans les tests unitaires sont beaucoup moins chers à corriger que ceux trouvés plus tard. L'investissement à court terme dans l'automatisation des tests et l'infrastructure de test unitaire porte ses fruits en améliorant la qualité des produits, la sécurité et la livraison dans les délais.

Malheureusement, quels que soient ces avantages, les développeurs ont encore du mal avec les tests unitaires, malgré le désir d'obtenir de meilleurs résultats. Ces luttes, également illustrées par les résultats de l'enquête ci-dessus, comprennent les éléments suivants.

  • La création de tests est un travail supplémentaire et souvent fastidieux. Naturellement, les tests unitaires représentent un travail supplémentaire et sont souvent considérés comme l'aspect le moins souhaitable de la programmation. La création d'une suite de tests complète tout en essayant de maintenir les objectifs et les délais du projet sont deux pressions concurrentes pour les équipes de développement.
  • La maintenance des tests coûte cher. Tout comme le code, les tests unitaires nécessitent une maintenance. Tout changement de code peut introduire des changements dans les tests associés. De plus, les tests qui échouent en raison de modifications de la base de code peuvent sembler sans rapport, ce qui entraîne une instabilité de la suite de tests. Une maintenance supplémentaire crée le double de travail dans l'esprit de nombreux développeurs.
  • La simulation et l'isolement des unités testées sont difficiles et prennent du temps. Il est essentiel d'isoler les unités testées, mais cela nécessite de se moquer des dépendances, ce qui peut prendre du temps.

Les équipes de développement logiciel doivent résoudre ces problèmes avec la création, l'isolation et la maintenance des tests si elles veulent profiter des avantages d'un test unitaire approfondi, et la solution est l'automatisation. Parasoft Jtest's outil de création automatique de tests unitaires fournit l'assistance dont les équipes ont besoin pour la création et la maintenance des tests tout en travaillant dans l'IDE du développeur et en tirant parti des frameworks de test et de simulation existants.

Réduisez la charge grâce à la création automatique de tests

La création de tests unitaires est fastidieuse et détourne l'attention des parties les plus intéressantes d'un projet. Le code lui-même est répétitif et nécessite souvent autant d'efforts que le code testé. En plus de cela, le code de test unitaire lui-même nécessite une correction et un débogage, comme le ferait n'importe quel code.

Heureusement, les tests unitaires se prêtent bien à l'automatisation. Le guidage automatique à partir d'un outil de test unitaire a ses avantages.

  • Simplifie grandement la création de tests.
  • Réduit la quantité de débogage et de correction.
  • Collecte les résultats et les métriques pour alimenter les analyses de projet.

Aller au-delà de l'IDE

De nombreux IDE fournissent des assistants de création de tests unitaires pour JUnit, par exemple, mais ne fournissent pas de "contenu" pour terminer le processus. Les assertions doivent être définies manuellement, et si des cadres factices sont utilisés, une quantité importante de codage manuel est nécessaire.

Au lieu de cela, Parasoft Jtest fournit une assistance contextuelle en temps réel dans l'IDE du développeur. Avec la création automatique de tests unitaires, le contenu manquant dans les tests unitaires simples squelette est complété rapidement et efficacement lorsque vous exploitez votre outil de test unitaire pour effectuer les opérations suivantes :

  • Créez un squelette de test, instanciez des objets, configurez des objets et des méthodes fictifs appropriés et ajoutez des assertions.
  • Identifiez les appels de méthode qui doivent être simulés pour mieux isoler le code testé.
  • Détectez les ressources système créées mais non libérées après la fin du test, créant potentiellement un environnement de test instable.
  • Collectez la couverture du code et d'autres mesures pour évaluer l'état du code et identifier les lacunes de couverture.
  • Optimisez la suite de tests en supprimant automatiquement les tests nouvellement générés qui ne contribuent pas à une couverture supplémentaire

Pour résoudre ce problème, regardons un exemple. Ici, Jtest ParasoftL'assistant de test unitaire de est utilisé dans un IDE pour créer une suite de tests :

Capture d'écran montrant l'option de menu Créer une suite de tests dans l'assistant de test unitaire de Parasoft Jtest utilisé dans un IDE.

L'outil crée plusieurs tests, chacun configuré pour couvrir un chemin distinct à travers la méthode testée. Par exemple, le code généré peut ressembler à ceci :

Capture d'écran montrant le code généré par l'assistant de test unitaire de Parasoft Jtest.

Notez que le test est préconfiguré avec des objets fictifs et des valeurs réelles, ainsi que des assertions sur le résultat de la méthode testée et tous les objets qui ont changé pendant l'exécution (dans ce cas, les champs de l'objet testé ont changé).

Réduisez la complexité moqueuse

Les tests unitaires impliquent l'isolement de l'objet testé, ce qui nécessite une bonne quantité de travail s'il existe de nombreuses dépendances. Même avec des frameworks moqueurs tels que mockito, il y a encore un important codage manuel requis. Avec un outil d'assistant de test automatisé, vous pouvez détecter les dépendances et remplir automatiquement les détails requis par le framework.

L'outil lui-même analyse le code testé, détecte automatiquement les dépendances et fait des recommandations au développeur.

Par exemple, supposons que nous exécutons un test unitaire contenant le code suivant qui se moque de la classe IWorkspaceClass :

Les dépendances sont détectées lors de l'exécution et l'outil recommande de se moquer des dépendances qu'il a trouvées :

La sélection de "Mock It" avec l'outil génère le code simulé nécessaire avec le test unitaire. Une fois ce code généré, il peut être personnalisé pour représenter la logique requise par le test. La détection automatisée des dépendances et la création ultérieure de code fictif réduisent considérablement la quantité de codage manuel, et potentiellement sujet aux erreurs, nécessaire pour simuler des objets.

Maintenance de la suite de tests réduite grâce à l'automatisation

La maintenance des suites de tests chevauche une grande partie du travail requis pour la création de tests, comme la création de nouveaux tests, la modification de tests pour couvrir correctement la logique sous-jacente, la simulation des dépendances et l'exécution de tests. L'assistance de l'assistant de test unitaire de Parasoft Jtest lors de la maintenance des tests est tout aussi précieuse que lors de la création, car elle fournit des résultats d'analyse d'exécution collectés lors de l'exécution des tests. Par exemple, une nouvelle dépendance dans un objet testé est détectée au moment de l'exécution et l'outil demande au développeur comment la traiter.

Il est tout aussi essentiel au cours de cette phase de s'assurer que les affirmations sont toujours valides. L'assistant de test d'unité Parasoft Jtest fournit des recommandations qui peuvent détecter les changements dans le code et mettre à jour les assertions pour refléter la nouvelle logique métier.

Maximiser les avantages des outils existants

Les développeurs Java utilisent déjà JUnit pour les tests unitaires et peut-être un framework factice pour leur projet, tel que Mockito. Les outils d'automatisation des tests doivent tirer parti de ces outils existants, car le remplacement d'un investissement existant dans les tests unitaires éliminerait tout avantage en termes de coût et de temps lié à l'utilisation d'un outil automatisé. L'assistant de test unitaire de Parasoft Jtest s'intègre parfaitement à ces outils existants, ce qui est essentiel.

Conclusion

Les tests unitaires présentent des avantages évidents. Bien que la plupart des équipes de développement s'en rendent compte, beaucoup sont bloquées par l'effort de création et de maintenance des tests. L'utilisation de technologies de tests unitaires automatisés comme celles de Parasoft Jtest aidera les utilisateurs à éliminer ces obstacles, en automatisant les aspects banals des tests unitaires, y compris la création, l'isolation, la simulation et la maintenance. Pour accélérer l'adoption, Parasoft Jtest s'appuie sur l'investissement existant de l'équipe de développement dans les frameworks de test et de simulation et redonne du temps au développeur tout en ramenant la qualité au produit.

Facilitez et accélérez les tests unitaires avec Parasoft Jtest compatible avec l'IA.